summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt80
-rw-r--r--src/H5.c37
-rw-r--r--src/H5A.c19
-rw-r--r--src/H5AS.c157
-rw-r--r--src/H5ASprivate.h47
-rw-r--r--src/H5ASpublic.h57
-rw-r--r--src/H5D.c14
-rw-r--r--src/H5Dselect.c1
-rw-r--r--src/H5ES.c1349
-rw-r--r--src/H5ESprivate.h77
-rw-r--r--src/H5ESpublic.h77
-rw-r--r--src/H5Edefin.h1
-rw-r--r--src/H5Einit.h5
-rw-r--r--src/H5Eprivate.h23
-rw-r--r--src/H5Epubgen.h2
-rw-r--r--src/H5Eterm.h1
-rw-r--r--src/H5F.c14
-rw-r--r--src/H5FF.c4623
-rw-r--r--src/H5FFprivate.h60
-rw-r--r--src/H5FFpublic.h226
-rw-r--r--src/H5FLprivate.h2
-rw-r--r--src/H5G.c14
-rw-r--r--src/H5Gloc.c2
-rw-r--r--src/H5I.c2
-rw-r--r--src/H5Iprivate.h1
-rw-r--r--src/H5Ipublic.h6
-rw-r--r--src/H5M.c1073
-rw-r--r--src/H5Mpublic.h74
-rw-r--r--src/H5Opublic.h1
-rw-r--r--src/H5Pdcpl.c22
-rw-r--r--src/H5Pdxpl.c72
-rw-r--r--src/H5Pencdec.c142
-rw-r--r--src/H5Pfapl.c30
-rw-r--r--src/H5Pint.c108
-rw-r--r--src/H5Plapl.c22
-rw-r--r--src/H5Pmapl.c118
-rw-r--r--src/H5Pmcpl.c118
-rw-r--r--src/H5Pocpl.c19
-rw-r--r--src/H5Ppkg.h4
-rw-r--r--src/H5Pprivate.h10
-rw-r--r--src/H5Ppublic.h20
-rw-r--r--src/H5Prcapl.c131
-rw-r--r--src/H5Ptrfpl.c132
-rw-r--r--src/H5Ptrspl.c131
-rw-r--r--src/H5Q.c1220
-rw-r--r--src/H5Qprivate.h100
-rw-r--r--src/H5Qpublic.h83
-rw-r--r--src/H5RC.c732
-rw-r--r--src/H5RCprivate.h70
-rw-r--r--src/H5RCpublic.h74
-rw-r--r--src/H5S.c6
-rw-r--r--src/H5Shyper.c76
-rw-r--r--src/H5Sprivate.h8
-rw-r--r--src/H5Spublic.h7
-rw-r--r--src/H5Sselect.c160
-rw-r--r--src/H5T.c10
-rw-r--r--src/H5TR.c829
-rw-r--r--src/H5TRprivate.h59
-rw-r--r--src/H5TRpublic.h71
-rw-r--r--src/H5Tcommit.c3
-rw-r--r--src/H5Tnative.c4
-rw-r--r--src/H5Tprivate.h4
-rw-r--r--src/H5VLint.c905
-rw-r--r--src/H5VLiod.c9251
-rw-r--r--src/H5VLiod.h83
-rw-r--r--src/H5VLiod_analysis.c1307
-rw-r--r--src/H5VLiod_attr.c1260
-rw-r--r--src/H5VLiod_client.c3015
-rw-r--r--src/H5VLiod_client.h450
-rw-r--r--src/H5VLiod_common.c1020
-rw-r--r--src/H5VLiod_common.h731
-rw-r--r--src/H5VLiod_dset.c1833
-rw-r--r--src/H5VLiod_dtype.c513
-rw-r--r--src/H5VLiod_encdec.c937
-rw-r--r--src/H5VLiod_file.c782
-rw-r--r--src/H5VLiod_group.c404
-rw-r--r--src/H5VLiod_link.c866
-rw-r--r--src/H5VLiod_map.c1079
-rw-r--r--src/H5VLiod_obj.c982
-rw-r--r--src/H5VLiod_server.c3795
-rw-r--r--src/H5VLiod_server.h436
-rw-r--r--src/H5VLiod_trans.c773
-rw-r--r--src/H5VLiod_util.c1288
-rw-r--r--src/H5VLiod_view.c409
-rw-r--r--src/H5VLprivate.h2
-rw-r--r--src/H5VLpublic.h15
-rw-r--r--src/H5checksum.c174
-rw-r--r--src/H5config.h.in51
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5private.h6
-rw-r--r--src/H5public.h15
-rw-r--r--src/H5trace.c219
-rw-r--r--src/Makefile.am11
-rw-r--r--src/Makefile.in84
-rw-r--r--src/hdf5.h6
-rw-r--r--src/libhdf5.settings.in1
96 files changed, 45139 insertions, 205 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eb43b3d..0b64414 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -463,12 +463,17 @@ SET (H5P_SRCS
${HDF5_SRC_DIR}/H5Pfcpl.c
${HDF5_SRC_DIR}/H5Pfmpl.c
${HDF5_SRC_DIR}/H5Pgcpl.c
+ ${HDF5_SRC_DIR}/H5Pmcpl.c
+ ${HDF5_SRC_DIR}/H5Pmapl.c
${HDF5_SRC_DIR}/H5Pint.c
${HDF5_SRC_DIR}/H5Plapl.c
${HDF5_SRC_DIR}/H5Plcpl.c
${HDF5_SRC_DIR}/H5Pocpl.c
${HDF5_SRC_DIR}/H5Pocpypl.c
${HDF5_SRC_DIR}/H5Pstrcpl.c
+ ${HDF5_SRC_DIR}/H5Prcapl.c
+ ${HDF5_SRC_DIR}/H5Ptrspl.c
+ ${HDF5_SRC_DIR}/H5Ptrfpl.c
${HDF5_SRC_DIR}/H5Ptest.c
)
@@ -487,6 +492,14 @@ SET (H5PL_HDRS
)
IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SRCS}" )
+SET (H5Q_SRCS
+ ${HDF5_SRC_DIR}/H5Q.c
+)
+
+SET (H5Q_HDRS
+ ${HDF5_SRC_DIR}/H5Qpublic.h
+)
+IDE_GENERATED_PROPERTIES ("H5Q" "${H5Q_HDRS}" "${H5Q_SRCS}" )
SET (H5R_SRCS
${HDF5_SRC_DIR}/H5R.c
@@ -617,11 +630,56 @@ SET (H5VL_SRCS
${HDF5_SRC_DIR}/H5VLint.c
${HDF5_SRC_DIR}/H5VLnative.c
)
+
SET (H5VL_HDRS
${HDF5_SRC_DIR}/H5VLpublic.h
${HDF5_SRC_DIR}/H5VLpkg.h
${HDF5_SRC_DIR}/H5VLnative.h
)
+
+IF (HDF5_ENABLE_EFF)
+ SET (H5FF_SRCS
+ ${HDF5_SRC_DIR}/H5AS.c
+ ${HDF5_SRC_DIR}/H5FF.c
+ ${HDF5_SRC_DIR}/H5M.c
+ ${HDF5_SRC_DIR}/H5ES.c
+ ${HDF5_SRC_DIR}/H5RC.c
+ ${HDF5_SRC_DIR}/H5TR.c
+ )
+ SET (H5FF_HDRS
+ ${HDF5_SRC_DIR}/H5ASpublic.h
+ ${HDF5_SRC_DIR}/H5FFpublic.h
+ ${HDF5_SRC_DIR}/H5Mpublic.h
+ ${HDF5_SRC_DIR}/H5ESpublic.h
+ ${HDF5_SRC_DIR}/H5RCpublic.h
+ ${HDF5_SRC_DIR}/H5TRpublic.h
+ )
+ IDE_GENERATED_PROPERTIES ("H5FF" "${H5FF_HDRS}" "${H5FF_SRCS}" )
+ SET (H5VL_SRCS
+ ${H5VL_SRCS}
+ ${HDF5_SRC_DIR}/H5VLiod.c
+ ${HDF5_SRC_DIR}/H5VLiod_common.c
+ ${HDF5_SRC_DIR}/H5VLiod_client.c
+ ${HDF5_SRC_DIR}/H5VLiod_server.c
+ ${HDF5_SRC_DIR}/H5VLiod_util.c
+ ${HDF5_SRC_DIR}/H5VLiod_file.c
+ ${HDF5_SRC_DIR}/H5VLiod_group.c
+ ${HDF5_SRC_DIR}/H5VLiod_dset.c
+ ${HDF5_SRC_DIR}/H5VLiod_dtype.c
+ ${HDF5_SRC_DIR}/H5VLiod_attr.c
+ ${HDF5_SRC_DIR}/H5VLiod_link.c
+ ${HDF5_SRC_DIR}/H5VLiod_obj.c
+ ${HDF5_SRC_DIR}/H5VLiod_map.c
+ ${HDF5_SRC_DIR}/H5VLiod_trans.c
+ ${HDF5_SRC_DIR}/H5VLiod_encdec.c
+ ${HDF5_SRC_DIR}/H5VLiod_analysis.c
+ )
+ SET (H5VL_HDRS
+ ${H5VL_HDRS}
+ ${HDF5_SRC_DIR}/H5VLiod.h
+ )
+ENDIF (HDF5_ENABLE_EFF)
+
IDE_GENERATED_PROPERTIES ("H5VL" "${H5VL_HDRS}" "${H5VL_SRCS}" )
SET (H5WB_SRCS
@@ -684,6 +742,7 @@ SET (common_SRCS
${H5O_SRCS}
${H5P_SRCS}
${H5PL_SRCS}
+ ${H5Q_SRCS}
${H5R_SRCS}
${H5UC_SRCS}
${H5RS_SRCS}
@@ -698,6 +757,12 @@ SET (common_SRCS
${H5WB_SRCS}
${H5Z_SRCS}
)
+IF (HDF5_ENABLE_EFF)
+ SET (common_SRCS
+ ${common_SRCS}
+ ${H5FF_SRCS}
+ )
+ENDIF (HDF5_ENABLE_EFF)
SET (H5_PUBLIC_HEADERS
${H5_HDRS}
@@ -725,6 +790,7 @@ SET (H5_PUBLIC_HEADERS
${H5O_HDRS}
${H5P_HDRS}
${H5PL_HDRS}
+ ${H5Q_HDRS}
${H5R_HDRS}
${H5S_HDRS}
${H5SM_HDRS}
@@ -732,6 +798,12 @@ SET (H5_PUBLIC_HEADERS
${H5VL_HDRS}
${H5Z_HDRS}
)
+IF (HDF5_ENABLE_EFF)
+ SET (H5_PUBLIC_HEADERS
+ ${H5_PUBLIC_HEADERS}
+ ${H5FF_HDRS}
+ )
+ENDIF (HDF5_ENABLE_EFF)
SET (H5_PRIVATE_HEADERS
@@ -765,6 +837,7 @@ SET (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5Oprivate.h
${HDF5_SRC_DIR}/H5Pprivate.h
${HDF5_SRC_DIR}/H5PLprivate.h
+ ${HDF5_SRC_DIR}/H5Qprivate.h
${HDF5_SRC_DIR}/H5UCprivate.h
${HDF5_SRC_DIR}/H5Rprivate.h
${HDF5_SRC_DIR}/H5RSprivate.h
@@ -780,6 +853,13 @@ SET (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5Zprivate.h
${HDF5_SRC_DIR}/H5win32defs.h
)
+IF (HDF5_ENABLE_EFF)
+ SET (H5_PRIVATE_HEADERS
+ ${H5_PRIVATE_HEADERS}
+ ${HDF5_SRC_DIR}/H5ASprivate.h
+ ${HDF5_SRC_DIR}/H5FFprivate.h
+ )
+ENDIF (HDF5_ENABLE_EFF)
INCLUDE_DIRECTORIES (${HDF5_SOURCE_DIR})
INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})
diff --git a/src/H5.c b/src/H5.c
index e11cbdf..98b1c13 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -255,9 +255,19 @@ H5_term_library(void)
pending += DOWN(D);
pending += DOWN(L);
pending += DOWN(G);
+#ifdef H5_HAVE_EFF
+ pending += DOWN(M);
+#endif /* H5_HAVE_EFF */
pending += DOWN(A);
pending += DOWN(S);
pending += DOWN(T);
+#ifdef H5_HAVE_EFF
+ pending += DOWN(TR);
+ pending += DOWN(RC);
+#endif /* H5_HAVE_EFF */
+ pending += DOWN(ES);
+ pending += DOWN(Q);
+
/* Don't shut down the file code until objects in files are shut down */
if(pending == 0)
pending += DOWN(F);
@@ -809,3 +819,30 @@ H5close(void)
FUNC_LEAVE_API_NOFS(SUCCEED)
} /* end H5close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5checksum
+ *
+ * Purpose: Generate a checksum for the data in Key.
+ * If the checksum is for a contiguous buffer, pass cs as NULL.
+ * if the checksum is for non contiguous buffer, intialize cs
+ * a,b,c,state to 0 and set the total_length to the size of the
+ * data. Then call H5checksum on every contiguous piece of the buffer
+ * with cs as the seed value from the previous H5checksum call.
+ *
+ * Programmer: Mohamad Chaarawi
+ * June 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+uint32_t H5checksum(const void *key, size_t length, H5_checksum_seed_t *cs)
+{
+ uint32_t ret_value;
+
+ FUNC_ENTER_API(0)
+
+ ret_value = H5_checksum_lookup4(key, length, cs);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5checksum */
diff --git a/src/H5A.c b/src/H5A.c
index cf4bc4d..bb5186c 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -223,7 +223,7 @@ H5A_term_interface(void)
/* ARGSUSED */
hid_t
H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
- hid_t acpl_id, hid_t UNUSED aapl_id)
+ hid_t acpl_id, hid_t aapl_id)
{
void *attr = NULL; /* attr token from VOL plugin */
void *obj = NULL; /* object token of loc_id */
@@ -365,7 +365,8 @@ H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
/* Create the attribute through the VOL */
- if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id, aapl_id, H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
+ if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id,
+ aapl_id, H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute")
/* Get an atom for the attribute */
@@ -1729,6 +1730,7 @@ done:
herr_t
H5Aclose(hid_t attr_id)
{
+ H5VL_t *vol_plugin = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -1738,6 +1740,13 @@ H5Aclose(hid_t attr_id)
if(NULL == H5I_object_verify(attr_id, H5I_ATTR))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = H5_EVENT_STACK_NULL;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
/* Decrement references to that atom (and close it) */
if(H5I_dec_app_ref(attr_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
@@ -1789,7 +1798,8 @@ H5Aexists(hid_t obj_id, const char *attr_name)
loc_params.obj_type = H5I_get_type(obj_id);
/* get the attribute info through the VOL */
- if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, H5AC_dxpl_id, H5_EVENT_STACK_NULL, loc_params, attr_name, &ret_value) < 0)
+ if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, H5AC_dxpl_id, H5_EVENT_STACK_NULL,
+ loc_params, attr_name, &ret_value) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info")
done:
@@ -1878,7 +1888,8 @@ H5A_close_attr(void *attr, H5VL_t *vol_plugin)
FUNC_ENTER_NOAPI_NOINIT
/* Close the attr through the VOL*/
- if((ret_value = H5VL_attr_close(attr, vol_plugin, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_attr_close(attr, vol_plugin, vol_plugin->close_dxpl_id,
+ vol_plugin->close_estack_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "unable to close attribute")
done:
diff --git a/src/H5AS.c b/src/H5AS.c
new file mode 100644
index 0000000..3a94a78
--- /dev/null
+++ b/src/H5AS.c
@@ -0,0 +1,157 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: Analysis shipping for local enumeration of data on remote storage.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+//#define H5_INTERFACE_INIT_FUNC H5AS_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5ASprivate.h" /* Analysis shipping */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h"
+#include "H5ESprivate.h" /* Event Stacks */
+
+#include "H5VLiod_client.h"
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ASexecute
+ *
+ * Purpose: Execute the query on file_name/obj_name, run split_script
+ * on the query result, combine the results and run combine_script.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ASexecute(const char *file_name, const char *obj_name, hid_t query_id,
+ const char *split_script, const char *combine_script, hid_t estack_id)
+{
+ H5Q_t *query;
+ herr_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "*s*si*s*si", file_name, obj_name, query_id, split_script,
+ combine_script, estack_id);
+
+ /* Check argument and retrieve object */
+ if(file_name == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file name")
+ if(obj_name == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL object name")
+ /*
+ if(NULL == (query = (H5Q_t *)H5I_object_verify(query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ */
+
+ /* It is allowed to have split_script and combine_script to be NULL */
+
+ /* H5AS_execute */
+ if((ret_value = H5AS_execute(file_name, obj_name, query_id, split_script,
+ combine_script, estack_id)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't start analysis"
+ "shipping execution")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ASexecute() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5AS_execute
+ *
+ * Purpose: Private routine for H5ASexecute.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AS_execute(const char *file_name, const char *obj_name, hid_t query_id,
+ const char *split_script, const char *combine_script, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file_name);
+ HDassert(obj_name);
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if (NULL == (request = (H5_priv_request_t *) H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_analysis_execute(file_name, obj_name, query_id,
+ split_script, combine_script, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL,
+ "can't start iod analysis shipping execution")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
+ "failed to insert request in event stack");
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5AS_execute */
diff --git a/src/H5ASprivate.h b/src/H5ASprivate.h
new file mode 100644
index 0000000..203990e
--- /dev/null
+++ b/src/H5ASprivate.h
@@ -0,0 +1,47 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 private information about the H5AS module
+ */
+#ifndef _H5ASprivate_H
+#define _H5ASprivate_H
+
+/* Include package's public header */
+#include "H5ASpublic.h"
+
+/* Private headers needed by this file */
+#include "H5Qprivate.h"
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+
+H5_DLL herr_t H5AS_execute(const char *file_name, const char *dataset_name,
+ hid_t query_id, const char *split_script, const char *combine_script,
+ hid_t estack_id);
+
+#endif /* _H5ASprivate_H */
diff --git a/src/H5ASpublic.h b/src/H5ASpublic.h
new file mode 100644
index 0000000..9cd8ffa
--- /dev/null
+++ b/src/H5ASpublic.h
@@ -0,0 +1,57 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 public information about the H5AS analysis shipping
+ * module. It implements the functions specified in the "Data Analysis
+ * Extensions" section of the Fast Forward HDF design document.
+ *
+ * The functionality should be provided as part of the server-side VOL process,
+ * i.e. this file should
+ */
+#ifndef _H5ASpublic_H
+#define _H5ASpublic_H
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/***************************/
+/* Library Public Typedefs */
+/***************************/
+
+/****************************/
+/* Library Public Variables */
+/****************************/
+
+/*****************************/
+/* Library Public Prototypes */
+/*****************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function prototypes */
+H5_DLL herr_t H5ASexecute(const char *file_name, const char *dataset_name,
+ hid_t query_id, const char *split_script, const char *combine_script,
+ hid_t estack_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5ASpublic_H */
diff --git a/src/H5D.c b/src/H5D.c
index c502dfc..aa43ea0 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -394,6 +394,7 @@ done:
herr_t
H5Dclose(hid_t dset_id)
{
+ H5VL_t *vol_plugin = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -403,6 +404,13 @@ H5Dclose(hid_t dset_id)
if(H5I_DATASET != H5I_get_type(dset_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = H5_EVENT_STACK_NULL;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
/*
* Decrement the counter on the dataset. It will be freed if the count
* reaches zero.
@@ -1033,7 +1041,8 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[])
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
/* set the extent through the VOL */
- if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5AC_dxpl_id,
+ H5_EVENT_STACK_NULL)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset")
done:
@@ -1063,7 +1072,8 @@ H5D_close_dataset(void *dset, H5VL_t *vol_plugin)
FUNC_ENTER_NOAPI_NOINIT
/* Close the dataset through the VOL*/
- if((ret_value = H5VL_dataset_close(dset, vol_plugin, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_dataset_close(dset, vol_plugin, vol_plugin->close_dxpl_id,
+ vol_plugin->close_estack_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset")
done:
diff --git a/src/H5Dselect.c b/src/H5Dselect.c
index 38f8bc4..2b9b31f 100644
--- a/src/H5Dselect.c
+++ b/src/H5Dselect.c
@@ -311,4 +311,3 @@ H5D__select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__select_write() */
-
diff --git a/src/H5ES.c b/src/H5ES.c
new file mode 100644
index 0000000..1ab3b63
--- /dev/null
+++ b/src/H5ES.c
@@ -0,0 +1,1349 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ * September, 2013
+ *
+ * Purpose: Wrappers around existing HDF5 to support Exascale FastForward
+ * functionality.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5ES_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5VLprivate.h" /* VOL plugins */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5ES_t struct */
+H5FL_DEFINE(H5ES_t);
+
+/* Dataspace ID class */
+static const H5I_class_t H5I_ES_CLS[1] = {{
+ H5I_ES, /* ID class value */
+ 0, /* Class flags */
+ 2, /* # of reserved IDs for class */
+ (H5I_free_t)H5ES_close, /* Callback routine for closing objects of this class */
+ NULL /* Callback routine for closing auxilary objects of this class */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_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 H5ES_init() */
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5ES_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5ES_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5ES_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Initialize the atom group for the ES IDs */
+ if(H5I_register_type(H5I_ES_CLS) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_init_interface() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5ES_term_interface
+ PURPOSE
+ Terminate various H5ES objects
+ USAGE
+ void H5ES_term_interface()
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5ES_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_interface_initialize_g) {
+ if((n = H5I_nmembers(H5I_ES))) {
+ H5I_clear_type(H5I_ES, FALSE, FALSE);
+ } /* end if */
+ else {
+ /* Free data types */
+ H5I_dec_type_ref(H5I_ES);
+
+ /* Shut down interface */
+ H5_interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5ES_term_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScreate
+ *
+ * Purpose: Creates an Event Stack used to manage async requests
+ *
+ * Return: Success: The ID for a new event stack.
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5EScreate(void)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ hid_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE0("i","");
+
+ /* Allocate the event stack structure */
+ if(NULL == (e_stack = H5FL_CALLOC(H5ES_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for event stack");
+
+ e_stack->head = e_stack->tail = NULL;
+ e_stack->size = 0;
+
+ /* Get an atom for the event stack with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register(H5I_ES, e_stack, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize event stack handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScreate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_insert
+ *
+ * Purpose: Inserts an async request into an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_insert(hid_t es_id, H5_priv_request_t *req)
+{
+ H5ES_t *e_stack = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check arguments. */
+ if(NULL == req)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "bad request");
+ if(H5I_ES != H5I_get_type(es_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event stack ID")
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object(es_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ req->next = NULL;
+ req->prev = NULL;
+
+ if(NULL == e_stack->head && NULL == e_stack->tail) {
+ e_stack->head = e_stack->tail = req;
+ }
+ else {
+ e_stack->head->prev = req;
+ req->next = e_stack->head;
+ e_stack->head = req;
+ }
+ e_stack->size ++;
+ e_stack->in_progress ++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESwait
+ *
+ * Purpose: Waits on an async request with the specified index in
+ * the Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESwait(hid_t es_id, size_t event_idx, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iz*Es", es_id, event_idx, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Wait request in the event stack */
+ if(H5ES_wait(e_stack, event_idx, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait request into event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESwait() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_wait
+ *
+ * Purpose: Private routine for H5ESwait
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_wait(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(event_idx >= e_stack->size)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "index is out of range for event stack")
+
+ cur = e_stack->head;
+ HDassert(NULL != cur);
+
+ for(u=0 ; u<event_idx ; u++) {
+ cur = cur->next;
+ HDassert(NULL != cur);
+ }
+
+ if(H5ES_STATUS_IN_PROGRESS == cur->status) {
+ /* wait on the request */
+ if(H5VL_request_wait(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+
+ e_stack->in_progress --;
+ cur->status = status;
+ }
+
+ *_status = cur->status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_wait() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESwait_all
+ *
+ * Purpose: Waits on all async requests in an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESwait_all(hid_t es_id, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Es", es_id, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Wait on all requests in the event stack */
+ if(H5ES_wait_all(e_stack, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait request into event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESwait_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_wait_all
+ *
+ * Purpose: Private routine for H5ESwait_all
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_wait_all(H5ES_t *e_stack, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ size_t succeed_count = 0, fail_count = 0, cancel_count = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(e_stack->size == 0) {
+ HGOTO_DONE(SUCCEED);
+ }
+
+ cur = e_stack->tail;
+
+ for(u=0 ; u<e_stack->size ; u++) {
+ HDassert(NULL != cur);
+
+ if(cur->status == H5ES_STATUS_IN_PROGRESS) {
+ /* wait on the request */
+ if(H5VL_request_wait(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+ e_stack->in_progress --;
+ cur->status = status;
+ }
+ else {
+ status = cur->status;
+ }
+
+ switch(status) {
+ case H5ES_STATUS_SUCCEED:
+ succeed_count ++;
+ break;
+ case H5ES_STATUS_FAIL:
+ fail_count ++;
+ break;
+ case H5ES_STATUS_CANCEL:
+ cancel_count ++;
+ break;
+ case H5ES_STATUS_IN_PROGRESS:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "waiting on request returned invalid status");
+ }
+
+ cur = cur->prev;
+ }
+
+ if(0 != e_stack->in_progress) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Failed to wait on all requests");
+ }
+
+ if(fail_count)
+ status = H5ES_STATUS_FAIL;
+ else if(cancel_count == e_stack->size)
+ status = H5ES_STATUS_CANCEL;
+ else if(succeed_count == e_stack->size ||
+ succeed_count+cancel_count == e_stack->size)
+ status = H5ES_STATUS_SUCCEED;
+
+ *_status = status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_wait_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EStest
+ *
+ * Purpose: Tests on an async request with the specified index in
+ * the Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5EStest(hid_t es_id, size_t event_idx, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iz*Es", es_id, event_idx, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Test request in the event stack */
+ if(H5ES_test(e_stack, event_idx, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request in event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EStest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_test
+ *
+ * Purpose: Private routine for H5EStest
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_test(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(event_idx >= e_stack->size)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "index is out of range for event stack")
+
+ cur = e_stack->head;
+
+ for(u=0 ; u<event_idx ; u++) {
+ HDassert(NULL != cur);
+ cur = cur->next;
+ }
+
+ if(H5ES_STATUS_IN_PROGRESS == cur->status) {
+ /* test on the request */
+ if(H5VL_request_test(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+
+ cur->status = status;
+
+ if(H5ES_STATUS_IN_PROGRESS != status)
+ e_stack->in_progress --;
+ }
+
+ *_status = cur->status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EStest_all
+ *
+ * Purpose: Tests on all async requests in an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5EStest_all(hid_t es_id, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Es", es_id, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Test on all requests in the event stack */
+ if(H5ES_test_all(e_stack, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request into event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EStest_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_test_all
+ *
+ * Purpose: Private routine for H5EStest_all
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_test_all(H5ES_t *e_stack, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ size_t succeed_count = 0, fail_count = 0, cancel_count = 0;
+ size_t in_progress_count = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(e_stack->size == 0) {
+ HGOTO_DONE(SUCCEED);
+ }
+
+ cur = e_stack->tail;
+
+ for(u=0 ; u<e_stack->size ; u++) {
+ HDassert(NULL != cur);
+
+ if(cur->status == H5ES_STATUS_IN_PROGRESS) {
+ /* test on the request */
+ if(H5VL_request_test(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+
+ if(status != H5ES_STATUS_IN_PROGRESS) {
+ cur->status = status;
+ e_stack->in_progress --;
+ }
+ }
+ else {
+ status = cur->status;
+ }
+
+ switch(status) {
+ case H5ES_STATUS_SUCCEED:
+ succeed_count ++;
+ break;
+ case H5ES_STATUS_FAIL:
+ fail_count ++;
+ break;
+ case H5ES_STATUS_CANCEL:
+ cancel_count ++;
+ break;
+ case H5ES_STATUS_IN_PROGRESS:
+ in_progress_count ++;
+ break;
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "testing on request returned invalid status");
+ }
+
+ cur = cur->prev;
+ }
+
+ HDassert(in_progress_count == e_stack->in_progress);
+
+ if(in_progress_count)
+ status = H5ES_STATUS_IN_PROGRESS;
+ else if(fail_count)
+ status = H5ES_STATUS_FAIL;
+ else if(cancel_count == e_stack->size)
+ status = H5ES_STATUS_CANCEL;
+ else if(succeed_count == e_stack->size ||
+ succeed_count+cancel_count == e_stack->size)
+ status = H5ES_STATUS_SUCCEED;
+
+ *_status = status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_test_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScancel
+ *
+ * Purpose: Cancels on an async request with the specified index in
+ * the Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5EScancel(hid_t es_id, size_t event_idx, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iz*Es", es_id, event_idx, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Cancel request in the event stack */
+ if(H5ES_cancel(e_stack, event_idx, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to cancel request in event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScancel() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_cancel
+ *
+ * Purpose: Private routine for H5EScancel
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_cancel(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(event_idx >= e_stack->size)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "index is out of range for event stack")
+
+ cur = e_stack->head;
+
+ for(u=0 ; u<event_idx ; u++) {
+ HDassert(NULL != cur);
+ cur = cur->next;
+ }
+
+ if(cur->status == H5ES_STATUS_IN_PROGRESS) {
+ /* cancel on the request */
+ if(H5VL_request_cancel(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to cancel request");
+
+ cur->status = status;
+ e_stack->in_progress --;
+ }
+
+ *_status = cur->status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_cancel() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScancel_all
+ *
+ * Purpose: Cancels on all async requests in an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5EScancel_all(hid_t es_id, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Es", es_id, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* Cancel on all requests in the event stack */
+ if(H5ES_cancel_all(e_stack, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to cancel request into event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScancel_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_cancel_all
+ *
+ * Purpose: Private routine for H5EScancel_all
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_cancel_all(H5ES_t *e_stack, H5ES_status_t *_status)
+{
+ H5_priv_request_t *cur = NULL;
+ size_t u = 0;
+ size_t succeed_count = 0, fail_count = 0, cancel_count = 0;
+ H5ES_status_t status;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(e_stack->size == 0) {
+ HGOTO_DONE(SUCCEED);
+ }
+
+ cur = e_stack->tail;
+
+ for(u=0 ; u<e_stack->size ; u++) {
+ HDassert(NULL != cur);
+
+ if(cur->status == H5ES_STATUS_IN_PROGRESS) {
+ /* cancel on the request */
+ if(H5VL_request_cancel(&cur->req, cur->vol_plugin, &status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to cancel request");
+ e_stack->in_progress --;
+ cur->status = status;
+ }
+ else {
+ status = cur->status;
+ }
+
+ switch(status) {
+ case H5ES_STATUS_SUCCEED:
+ succeed_count ++;
+ break;
+ case H5ES_STATUS_FAIL:
+ fail_count ++;
+ break;
+ case H5ES_STATUS_CANCEL:
+ cancel_count ++;
+ break;
+ case H5ES_STATUS_IN_PROGRESS:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "canceling on request returned invalid status");
+ }
+
+ cur = cur->prev;
+ }
+
+ if(0 != e_stack->in_progress) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Failed to wait on all requests");
+ }
+
+ if(fail_count)
+ status = H5ES_STATUS_FAIL;
+ else if(cancel_count == e_stack->size)
+ status = H5ES_STATUS_CANCEL;
+ else if(succeed_count == e_stack->size ||
+ succeed_count+cancel_count == e_stack->size)
+ status = H5ES_STATUS_SUCCEED;
+
+ *_status = status;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_cancel_all() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_count
+ *
+ * Purpose: Returns number of events in event stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_count(hid_t es_id, size_t *count)
+{
+ H5ES_t *e_stack = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*z", es_id, count);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ *count = e_stack->size;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESclear
+ *
+ * Purpose: Clear all events from the event stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESclear(hid_t es_id)
+{
+ H5ES_t *e_stack = NULL;
+ H5_priv_request_t *tail = NULL, *prev = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", es_id);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ if(e_stack->size == 0) {
+ HGOTO_DONE(SUCCEED);
+ }
+
+ if(0 != e_stack->in_progress)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't clear stack with events in progress")
+
+ while(e_stack->tail) {
+ /* Pop the last item and manage the stack accordingly */
+ tail = e_stack->tail;
+ prev = tail->prev;
+ e_stack->tail = prev;
+
+ if(NULL == e_stack->tail)
+ e_stack->head = e_stack->tail;
+
+ /* free the request */
+ HDassert(H5ES_STATUS_IN_PROGRESS != tail->status);
+
+ tail->vol_plugin->nrefs --;
+ if (0 == tail->vol_plugin->nrefs) {
+ tail->vol_plugin->container_name = H5MM_xfree(tail->vol_plugin->container_name);
+ tail->vol_plugin = (H5VL_t *)H5MM_xfree(tail->vol_plugin);
+ }
+ tail->vol_plugin = NULL;
+ tail->req = NULL;
+ tail->next = NULL;
+ tail->prev = NULL;
+ tail = (H5_priv_request_t *)H5MM_xfree(tail);
+
+ e_stack->size --;
+ }
+
+ HDassert(0 == e_stack->size);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESclear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESclose
+ *
+ * Purpose: Closes the specified event stack. The ID will no longer be
+ * valid for accessing the event stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESclose(hid_t es_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", es_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(es_id,H5I_ES))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event stack")
+
+ if(H5I_dec_app_ref(es_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESclose() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_close
+ *
+ * Purpose: Close an event stack object
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_close(H5ES_t *e_stack)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ e_stack = H5FL_FREE(H5ES_t, e_stack);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5ES_close() */
+
+#if 0
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScreate
+ *
+ * Purpose: Creates an Event Stack used to manage async requests
+ *
+ * Return: Success: The ID for a new event stack.
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5EScreate(hid_t fapl_id)
+{
+ void *e_stack = NULL; /* event stack token */
+ H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */
+ H5VL_t *vol_plugin = NULL; /* VOL plugin information from fapl */
+ H5P_genplist_t *plist; /* Property list pointer */
+ hid_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("i", "i", fapl_id);
+
+ /* Check the file access property list */
+ if(H5P_DEFAULT == fapl_id)
+ fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin ID")
+
+ /* Build the vol plugin struct */
+ if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ vol_plugin = *plugin;
+ vol_plugin->cls = vol_cls;
+ vol_plugin->nrefs = 1;
+ vol_plugin->container_name = NULL;
+
+ /* Allocate the event stack structure */
+ if(NULL == (e_stack = H5FL_CALLOC(H5ES_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for event stack");
+
+ e_stack->head = e_stack->tail = NULL;
+ e_stack->size = 0;
+
+ /* Get an atom for the event stack with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register2(H5I_ES, e_stack, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize event stack handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScreate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScreate
+ *
+ * Purpose: Creates an Event Stack used to manage async requests
+ *
+ * Return: Success: The ID for a new event stack.
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+H5ES_t *
+H5ES_create(H5VL_t **plugin, H5P_genplist_t *plist)
+{
+ H5ES_t *eq = NULL; /* Event Stack object */
+ H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */
+ H5VL_t *vol_plugin = NULL; /* the public VOL struct */
+ H5ES_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID")
+
+ /* Allocate the event stack structure */
+ if(NULL == (eq = H5FL_CALLOC(H5ES_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for event stack");
+
+ eq->head = eq->tail = NULL;
+ eq->size = 0;
+
+ /* Build the vol plugin struct */
+ if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ vol_plugin = *plugin;
+ vol_plugin->cls = vol_cls;
+ vol_plugin->nrefs = 1;
+ vol_plugin->container_name = NULL;
+
+ ret_value = eq;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESpop
+ *
+ * Purpose: retrieves the top async request from an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESpop(hid_t es_id, H5_request_t *req)
+{
+ H5ES_t *eq = NULL; /* event stack token */
+ H5_priv_request_t *priv_req = NULL; /* internal request struct */
+ H5_priv_request_t *head = NULL;
+ H5_priv_request_t *next = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*x", es_id, req);
+
+ /* Check arguments. */
+ if(H5I_ES != H5I_get_type(es_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event stack ID")
+
+ /* get the eq object */
+ if(NULL == (eq = (H5ES_t *)H5I_object(es_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier");
+
+ priv_req = eq->head;
+
+ head = eq->head;
+ next = head->next;
+
+ eq->head = next;
+ if(NULL == eq->head)
+ eq->tail = eq->head;
+
+ eq->size --;
+
+ *req = (H5_request_t) priv_req;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESpop() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESwait
+ *
+ * Purpose: Waits on all async requests in an Event Stack.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESwait(hid_t es_id, size_t event_idx, H5ES_status_t *status)
+{
+ H5ES_t *e_stack = NULL; /* event stack token */
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event stack should use */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iz*Es", es_id, event_idx, status);
+
+ /* get the e_stack object */
+ if(NULL == (e_stack = (H5ES_t *)H5I_object_verify(es_id, H5I_ES)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event stack identifier")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(es_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ /* Wait request in the event stack */
+ if(H5ES_wait(e_stack, vol_plugin, event_idx, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait request into event stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESwait() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AOcancel
+ *
+ * Purpose: Cancel an asynchronous operation
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AOcancel(H5_request_t req, H5ES_status_t *status)
+{
+ H5_priv_request_t *request = (H5_priv_request_t *)req;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "x*Es", req, status);
+
+ if(H5VL_request_cancel(&request->req, request->vol_plugin, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to cancel request");
+
+ request->req = NULL;
+ request->vol_plugin = NULL;
+ request->next = NULL;
+ request = (H5_priv_request_t *)H5MM_xfree(request);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5AOcancel() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AOtest
+ *
+ * Purpose: Test for an asynchronous operation's completion
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AOtest(H5_request_t req, H5ES_status_t *status)
+{
+ H5_priv_request_t *request = (H5_priv_request_t *)req;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "x*Es", req, status);
+
+ if(H5VL_request_test(&request->req, request->vol_plugin, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+
+ if(*status != H5AO_PENDING) {
+ request->req = NULL;
+ request->vol_plugin = NULL;
+ request->next = NULL;
+ request = (H5_priv_request_t *)H5MM_xfree(request);
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5AOtest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AOwait
+ *
+ * Purpose: Wait for an asynchronous operation to complete
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5AOwait(H5_request_t req, H5ES_status_t *status)
+{
+ H5_priv_request_t *request = (H5_priv_request_t *)req;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "x*Es", req, status);
+
+ if(H5VL_request_wait(&request->req, request->vol_plugin, status) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request");
+
+ request->req = NULL;
+ request->vol_plugin = NULL;
+ request->next = NULL;
+ request = (H5_priv_request_t *)H5MM_xfree(request);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5AOwait() */
+
+#endif
diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h
new file mode 100644
index 0000000..a1b8821
--- /dev/null
+++ b/src/H5ESprivate.h
@@ -0,0 +1,77 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 private information about the H5ES module
+ */
+#ifndef _H5ESprivate_H
+#define _H5ESprivate_H
+
+/* Include package's public header */
+#include "H5ESpublic.h"
+
+/* Private headers needed by this file */
+#include "H5private.h" /* Generic Functions */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5VLprivate.h" /* VOL plugins */
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* The private request structure */
+typedef struct H5_priv_request_t {
+ void *req; /* pointer to the request belonging to a VOL plugin */
+ H5VL_t *vol_plugin; /* the vol plugin that owns this request */
+ H5ES_status_t status;
+ struct H5_priv_request_t *prev;
+ struct H5_priv_request_t *next;
+} H5_priv_request_t;
+
+/* The private request structure */
+typedef struct H5ES_t {
+ size_t size; /* number of events in the stack */
+ size_t in_progress; /* number of events that the user did not call wait on */
+ H5_priv_request_t *head;
+ H5_priv_request_t *tail;
+} H5ES_t;
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+
+herr_t H5ES_init(void);
+
+/* API wrappers */
+H5_DLL H5ES_t *H5ES_create(H5VL_t **plugin, H5P_genplist_t *plist);
+H5_DLL herr_t H5ES_insert(hid_t es_id, H5_priv_request_t *req);
+H5_DLL herr_t H5ES_wait(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_wait_all(H5ES_t *e_stack, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_test(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_test_all(H5ES_t *e_stack, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_cancel(H5ES_t *e_stack, size_t event_idx, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_cancel_all(H5ES_t *e_stack, H5ES_status_t *_status/*OUT*/);
+H5_DLL herr_t H5ES_close(H5ES_t *e_stack);
+
+#endif /* _H5ESprivate_H */
diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h
new file mode 100644
index 0000000..a33a3d6
--- /dev/null
+++ b/src/H5ESpublic.h
@@ -0,0 +1,77 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+ * H5ES module.
+ */
+#ifndef _H5ESpublic_H
+#define _H5ESpublic_H
+
+/* System headers needed by this file */
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/* Asynchronous operation status */
+typedef enum H5ES_status_t {
+ H5ES_STATUS_IN_PROGRESS, /* Operation has not yet completed */
+ H5ES_STATUS_SUCCEED, /* Operation has completed, successfully */
+ H5ES_STATUS_FAIL, /* Operation has completed, but failed */
+ H5ES_STATUS_CANCEL /* Operation has not completed and has been cancelled */
+} H5ES_status_t;
+
+/********************/
+/* Public Variables */
+/********************/
+
+
+#define H5_REQUEST_NULL NULL
+#define H5_EVENT_STACK_NULL -1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+H5_DLL hid_t H5EScreate(void);
+H5_DLL herr_t H5ESget_count(hid_t es_id, size_t *count);
+ //H5_DLL herr_t H5ESget_event_info(hid_t es_id, size_t start_idx, size_t count,
+ //const char *ev_trace_str_arr[], H5ES_status_t ev_status_arr[],
+ //H5E_stack_id ev_err_stack_id_arr[]);
+H5_DLL herr_t H5EStest(hid_t es_id, size_t event_idx, H5ES_status_t *status);
+H5_DLL herr_t H5EStest_all(hid_t es_id, H5ES_status_t *status);
+H5_DLL herr_t H5ESwait(hid_t es_id, size_t event_idx, H5ES_status_t *status);
+H5_DLL herr_t H5ESwait_all(hid_t es_id, H5ES_status_t *status);
+H5_DLL herr_t H5EScancel(hid_t es_id, size_t event_idx, H5ES_status_t *status);
+H5_DLL herr_t H5EScancel_all(hid_t es_id, H5ES_status_t *status);
+H5_DLL herr_t H5ESclear(hid_t es_id);
+H5_DLL herr_t H5ESclose(hid_t es_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5ESpublic_H */
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 4c4b4df..1f0d86a 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -40,6 +40,7 @@ hid_t H5E_ATTR_g = FAIL; /* Attribute */
hid_t H5E_IO_g = FAIL; /* Low-level I/O */
hid_t H5E_EFL_g = FAIL; /* External file list */
hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */
+hid_t H5E_QUERY_g = FAIL; /* Query */
hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
hid_t H5E_DATASET_g = FAIL; /* Dataset */
hid_t H5E_STORAGE_g = FAIL; /* Data storage */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 75c0b70..8a2c144 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -119,6 +119,11 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_QUERY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Query"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_QUERY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FSPACE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index 0e6def6..1bb55aa 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -69,6 +69,29 @@ typedef struct H5E_t H5E_t;
HGOTO_DONE(ret_val) \
}
+#define HGOTO_ERROR_IOD(iod_ret, ret_val, string) { \
+ fprintf(stderr, "%s\n", string); \
+ fprintf(stderr, "%d (%s).\n", iod_ret, strerror(-iod_ret)); \
+ HGOTO_DONE(ret_val) \
+}
+
+#define HGOTO_ERROR_FF(ret_val, string) { \
+ fprintf(stderr, "%s\n", string); \
+ HGOTO_DONE(ret_val) \
+}
+
+#define HGOTO_ERROR2(maj, min, ret_val, string) { \
+ fprintf(stderr, "%s\n", string); \
+ err_occurred = TRUE; \
+ err_occurred = err_occurred; /* Shut GCC warnings up! */ \
+ HGOTO_DONE(ret_val) \
+}
+
+#define HDONE_ERROR2(maj, min, ret_val, string) { \
+ fprintf(stderr, "%s\n", string); \
+ ret_value = ret_val; \
+}
+
/*
* HGOTO_ERROR_TAG macro, used like HGOTO_ERROR between H5_BEGIN_TAG and
* H5_END_TAG statements. Resets the metadata tag before leaving the function.
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index e5ecd10..f0d4242 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -43,6 +43,7 @@
#define H5E_IO (H5OPEN H5E_IO_g)
#define H5E_EFL (H5OPEN H5E_EFL_g)
#define H5E_TST (H5OPEN H5E_TST_g)
+#define H5E_QUERY (H5OPEN H5E_QUERY_g)
#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
#define H5E_DATASET (H5OPEN H5E_DATASET_g)
#define H5E_STORAGE (H5OPEN H5E_STORAGE_g)
@@ -77,6 +78,7 @@ H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */
H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */
H5_DLLVAR hid_t H5E_EFL_g; /* External file list */
H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */
+H5_DLLVAR hid_t H5E_QUERY_g; /* Query */
H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index aecef3e..de0db21 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -41,6 +41,7 @@ H5E_ATTR_g=
H5E_IO_g=
H5E_EFL_g=
H5E_TST_g=
+H5E_QUERY_g=
H5E_FSPACE_g=
H5E_DATASET_g=
H5E_STORAGE_g=
diff --git a/src/H5F.c b/src/H5F.c
index e961681..30f67c0 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -626,7 +626,8 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list")
/* create a new file or truncate an existing file through the VOL */
- if(NULL == (file = H5VL_file_create(&vol_plugin, filename, flags, fcpl_id, fapl_id, H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
+ if(NULL == (file = H5VL_file_create(&vol_plugin, filename, flags, fcpl_id, fapl_id,
+ H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file")
/* Get an atom for the file with the VOL information as the auxilary struct*/
@@ -789,6 +790,7 @@ done:
herr_t
H5Fclose(hid_t file_id)
{
+ H5VL_t *vol_plugin = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
@@ -798,6 +800,13 @@ H5Fclose(hid_t file_id)
if(H5I_FILE != H5I_get_type(file_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = H5_EVENT_STACK_NULL;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
/* Decrement reference count on atom. When it reaches zero the file will be closed. */
if(H5I_dec_app_ref(file_id) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed")
@@ -847,7 +856,8 @@ H5F_close_file(void *file, H5VL_t *vol_plugin)
FUNC_ENTER_NOAPI_NOINIT
/* Close the file through the VOL*/
- if((ret_value = H5VL_file_close(file, vol_plugin, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_file_close(file, vol_plugin, vol_plugin->close_dxpl_id,
+ vol_plugin->close_estack_id)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5FF.c b/src/H5FF.c
new file mode 100644
index 0000000..c4875ed
--- /dev/null
+++ b/src/H5FF.c
@@ -0,0 +1,4623 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ * March, 2013
+ *
+ * Purpose: Wrappers around existing HDF5 to support Exascale FastForward
+ * functionality.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5A_PACKAGE /*suppress error about including H5Apkg */
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5T_PACKAGE /*suppress error about including H5Tpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5FF__init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Apkg.h" /* Attribute access */
+#include "H5Dpkg.h" /* Dataset access */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
+#include "H5Fpkg.h" /* File access */
+#include "H5FFprivate.h" /* FastForward wrappers */
+#include "H5Gpkg.h" /* Group access */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Tpkg.h" /* Datatype access */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod.h" /* IOD plugin - tmp */
+#include "H5VLiod_client.h" /* Client IOD - tmp */
+
+#ifdef H5_HAVE_EFF
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+static herr_t
+H5FF__init_interface(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ if(H5F_init() < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init file interface")
+
+ if(H5G__init() < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init group interface")
+
+ if(H5D_init() < 0)
+ 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")
+
+ if(H5M_init() < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface")
+
+ if(H5RC_init() < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5FF__init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fcreate_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Fcreate().
+ *
+ * Return: Success: The placeholder ID for a new file. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t estack_id)
+{
+ void *file = NULL; /* file token from VOL plugin */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "*sIuiii", filename, flags, fcpl_id, fapl_id, estack_id);
+
+ /* Check/fix arguments */
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name")
+ /* In this routine, we only accept the following flags:
+ * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG
+ */
+ if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags")
+ /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */
+ if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation")
+
+ /* Check file creation property list */
+ if(H5P_DEFAULT == fcpl_id)
+ fcpl_id = H5P_FILE_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list")
+
+ /* Check the file access property list */
+ if(H5P_DEFAULT == fapl_id)
+ fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list")
+
+ /* create a new file or truncate an existing file through the VOL */
+ if(NULL == (file = H5VL_file_create(&vol_plugin, filename, flags, fcpl_id, fapl_id,
+ H5AC_dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file")
+
+ /* Get an atom for the file with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fcreate_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fopen_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Fopen().
+ *
+ * Return: Success: The placeholder ID for a new file. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id,
+ hid_t *rcxt_id, hid_t estack_id)
+{
+ void *file = NULL; /* file token from VOL plugin */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "*sIui*ii", filename, flags, fapl_id, rcxt_id, estack_id);
+
+ /* Check/fix arguments. */
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name")
+ /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */
+ if((flags & ~H5F_ACC_PUBLIC_FLAGS) ||
+ (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
+ if(H5P_DEFAULT == fapl_id)
+ fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list")
+
+ /* determine if we want to acquire the latest readable version
+ when the file is opened */
+ if(rcxt_id) {
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ H5RC_t *rc = NULL;
+
+ /* create a new read context object (if user requested it) */
+ if(NULL == (rc = H5RC_create(file, IOD_TID_UNKNOWN)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create read context");
+ /* Get an atom for the event queue with the VOL information as the auxilary struct */
+ if((*rcxt_id = H5I_register(H5I_RC, rc, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize read context handle");
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_ACQUIRE_RC_ID, rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rxct id")
+ }
+
+ /* Open the file through the VOL layer */
+ if(NULL == (file = H5VL_file_open(&vol_plugin, filename, flags, fapl_id,
+ H5AC_dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file")
+
+ if(rcxt_id) {
+ /* attach VOL information to the ID */
+ if (H5I_register_aux(*rcxt_id, vol_plugin) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID")
+ }
+
+ /* Get an atom for the file with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fopen_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fclose_ff
+ *
+ * Purpose: This function closes the file specified by FILE_ID by
+ * flushing all data to storage, and terminating access to the
+ * file through FILE_ID. If objects (e.g., datasets, groups,
+ * etc.) are open in the file then the underlying storage is not
+ * closed until those objects are closed; however, all data for
+ * the file and the open objects is flushed.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fclose_ff(hid_t file_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", file_id, estack_id);
+
+ /* Check/fix arguments. */
+ if(H5I_FILE != H5I_get_type(file_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /* Decrement reference count on atom. When it reaches zero the file will be closed. */
+ if(H5I_dec_app_ref(file_id) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fclose_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gcreate_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Gcreate().
+ *
+ * Return: Success: The placeholder ID for a group. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gcreate_ff(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id,
+ hid_t trans_id, hid_t estack_id)
+{
+ void *grp = NULL; /* dset token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5VL_loc_params_t loc_params;
+ H5P_genplist_t *plist; /* Property list pointer */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("i", "i*siiiii", loc_id, name, lcpl_id, gcpl_id, gapl_id, trans_id,
+ estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Check group creation property list */
+ if(H5P_DEFAULT == gcpl_id)
+ gcpl_id = H5P_GROUP_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_set(plist, H5VL_GRP_LCPL_ID, &lcpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the location object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Create the group through the VOL */
+ if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, name, gcpl_id, gapl_id,
+ dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
+
+ /* Get an atom for the group */
+ if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle")
+
+done:
+ if (ret_value < 0 && grp)
+ if(H5VL_group_close (grp, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gcreate_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gopen_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Gopen().
+ *
+ * Return: Success: The placeholder ID for a group. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gopen_ff(hid_t loc_id, const char *name, hid_t gapl_id,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ void *grp = NULL; /* dset token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "i*siii", loc_id, name, gapl_id, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Create the group through the VOL */
+ if(NULL == (grp = H5VL_group_open(obj, loc_params, vol_plugin, name, gapl_id,
+ dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
+
+ /* Get an atom for the group */
+ if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gopen_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gclose_ff
+ *
+ * Purpose: Closes the specified group. The group ID will no longer be
+ * valid for accessing the group.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gclose_ff(hid_t group_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", group_id, estack_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(group_id,H5I_GROUP))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(group_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /*
+ * Decrement the counter on the group atom. It will be freed if the count
+ * reaches zero.
+ */
+ if(H5I_dec_app_ref(group_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gclose_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dcreate_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Dcreate().
+ *
+ * Return: Success: The placeholder ID for a new dataset. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
+ hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *dset = NULL; /* dset token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5VL_loc_params_t loc_params;
+ H5P_genplist_t *plist; /* Property list pointer */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("i", "i*siiiiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id,
+ dapl_id, trans_id, estack_id);
+
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dcpl_id)
+ dcpl_id = H5P_DATASET_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_DSET_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id")
+ if(H5P_set(plist, H5VL_DSET_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id")
+ if(H5P_set(plist, H5VL_DSET_LCPL_ID, &lcpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Create the dataset through the VOL */
+ if(NULL == (dset = H5VL_dataset_create(obj, loc_params, vol_plugin, name, dcpl_id, dapl_id,
+ dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
+
+ /* Get an atom for the dataset */
+ if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && dset)
+ if(H5VL_dataset_close(dset, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dcreate_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dopen_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Dopen().
+ *
+ * Return: Success: The placeholder ID for a dataset. When
+ * the asynchronous operation completes, this
+ * ID will transparently be modified to be a
+ * "normal" ID.
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *dset = NULL; /* dset token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "i*siii", loc_id, name, dapl_id, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Create the dataset through the VOL */
+ if(NULL == (dset = H5VL_dataset_open(obj, loc_params, vol_plugin, name,
+ dapl_id, dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset")
+
+ /* Get an atom for the dataset */
+ if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && dset)
+ if(H5VL_dataset_close (dset, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dopen_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dwrite_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Dwrite().
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dwrite_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, const void *buf,
+ hid_t trans_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *dset;
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "iiiii*xii", dset_id, mem_type_id, mem_space_id, file_space_id,
+ dxpl_id, buf, trans_id, estack_id);
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ /* 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")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (dset = (void *)H5I_object(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+
+ /* Write the data through the VOL */
+ if((ret_value = H5VL_dataset_write(dset, vol_plugin, mem_type_id, mem_space_id,
+ file_space_id, dxpl_id, buf, estack_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dwrite_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dread_ff
+ *
+ * Purpose: Asynchronous wrapper around H5Dread().
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dread_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, void *buf,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *dset;
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "iiiii*xii", dset_id, mem_type_id, mem_space_id, file_space_id,
+ dxpl_id, buf, rcxt_id, estack_id);
+
+ if(mem_space_id < 0 || file_space_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+
+ /* 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 plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (dset = (void *)H5I_object(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Read the data through the VOL */
+ if((ret_value = H5VL_dataset_read(dset, vol_plugin, mem_type_id, mem_space_id,
+ file_space_id, dxpl_id, buf, estack_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dread_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dset_extent_ff
+ *
+ * Purpose: Modifies the dimensions of a dataset.
+ * Can change to a smaller dimension.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dset_extent_ff(hid_t dset_id, const hsize_t size[], hid_t trans_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *dset;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*hii", dset_id, size, trans_id, estack_id);
+
+ if(!size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (dset = (void *)H5I_object(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+
+ /* set the extent through the VOL */
+ if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dset_extent_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dclose_ff
+ *
+ * Purpose: Closes access to a dataset (DATASET_ID) and releases
+ * resources used by it. It is illegal to subsequently use that
+ * same dataset ID in calls to other dataset functions.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dclose_ff(hid_t dset_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", dset_id, estack_id);
+
+ /* Check/fix arguments. */
+ if(H5I_DATASET != H5I_get_type(dset_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /*
+ * Decrement the counter on the dataset. It will be freed if the count
+ * reaches zero.
+ *
+ * Pass in TRUE for the 3rd parameter to tell the function to remove
+ * dataset's ID even though the freeing function might fail. Please
+ * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7)
+ */
+ if(H5I_dec_app_ref_always_close(dset_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dclose() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommit_ff
+ *
+ * Purpose: Save a transient datatype to a file and turn the type handle
+ * into a "named", immutable type.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tcommit_ff(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id,
+ hid_t tcpl_id, hid_t tapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *dt = NULL;
+ H5T_t *type = NULL;
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*siiiiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id,
+ trans_id, estack_id);
+
+ /* Check arguments */
+ if (H5Tcommitted(type_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tcpl_id)
+ tcpl_id = H5P_DATATYPE_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tcpl_id, H5P_DATATYPE_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype creation property list")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tapl_id)
+ tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
+
+ if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the object from the loc_id */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* commit the datatype through the VOL */
+ if (NULL == (dt = H5VL_datatype_commit(obj, loc_params, vol_plugin, name, type_id, lcpl_id,
+ tcpl_id, tapl_id, dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to commit datatype")
+
+ /* attach the vol object created using the commit call to the
+ library datatype structure */
+ /* set the committed type object to the VOL pluging pointer in the H5T_t struct */
+ type->vol_obj = dt;
+
+ /* attach VOL information to the ID */
+ if (H5I_register_aux(type_id, vol_plugin) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tcommit_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Topen_ff
+ *
+ * Purpose: Opens a named datatype using a Datatype Access Property
+ * List.
+ *
+ * Return: Success: Object ID of the named datatype.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen_ff(hid_t loc_id, const char *name, hid_t tapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *vol_dt = NULL; /* datatype token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5T_t *dt = NULL;
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value = FAIL; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "i*siii", loc_id, name, tapl_id, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tapl_id)
+ tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Create the datatype through the VOL */
+ if(NULL == (vol_dt = H5VL_datatype_open(obj, loc_params, vol_plugin, name, tapl_id,
+ dxpl_id, H5_EVENT_STACK_NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open datatype");
+
+ /* Get an atom for the datatype */
+ if ((ret_value = H5VL_create_datatype(vol_dt, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle");
+
+ /* Get an atom for the datatype with the VOL information as the auxilary struct*/
+ //if((ret_value = H5I_register2(H5I_DATATYPE, dt, vol_plugin, app_ref)) < 0)
+ //HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
+
+done:
+ if (ret_value < 0 && dt)
+ if(H5VL_datatype_close (dt, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Topen_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tclose_ff
+ *
+ * Purpose: Frees a datatype and all associated memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tclose_ff(hid_t type_id, hid_t estack_id)
+{
+ H5T_t *dt; /* Pointer to datatype to close */
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", type_id, estack_id);
+
+ /* Check args */
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(H5T_STATE_IMMUTABLE == dt->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /* When the reference count reaches zero the resources are freed */
+ if(H5I_dec_app_ref(type_id) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tclose_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Acreate_ff
+ PURPOSE
+ Creates an attribute on an object
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+hid_t
+H5Acreate_ff(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
+ hid_t acpl_id, hid_t aapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *attr = NULL; /* attr token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("i", "i*siiiiii", loc_id, attr_name, type_id, space_id, acpl_id,
+ aapl_id, trans_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == acpl_id)
+ acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id")
+ if(H5P_set(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Create the attribute through the VOL */
+ if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id, aapl_id,
+ dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute")
+
+ /* Get an atom for the attribute */
+ if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && attr)
+ if(H5VL_attr_close (attr, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Acreate_by_name_ff
+ PURPOSE
+ Creates an attribute on an object
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+hid_t
+H5Acreate_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *attr = NULL; /* attr token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("i", "i*s*siiiiiii", loc_id, obj_name, attr_name, type_id, space_id,
+ acpl_id, aapl_id, lapl_id, trans_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == acpl_id)
+ acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id")
+ if(H5P_set(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.obj_type = H5I_get_type(loc_id);
+ loc_params.loc_data.loc_by_name.name = obj_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Create the attribute through the VOL */
+ if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id,
+ aapl_id, dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute")
+
+ /* Get an atom for the attribute */
+ if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && attr)
+ if(H5VL_attr_close (attr, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate_by_name_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Aopen_ff
+ PURPOSE
+ Opens an attribute for an object by looking up the attribute name
+ RETURNS
+ ID of attribute on success, negative on failure
+--------------------------------------------------------------------------*/
+hid_t
+H5Aopen_ff(hid_t loc_id, const char *attr_name, hid_t aapl_id,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ void *attr = NULL; /* attr token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "i*siii", loc_id, attr_name, aapl_id, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Create the attribute through the VOL */
+ if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, attr_name, aapl_id, dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute")
+
+ /* Get an atom for the attribute */
+ if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && attr)
+ if(H5VL_attr_close (attr, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aopen_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Aopen_by_name_ff
+ PURPOSE
+ Opens an attribute for an object by looking up the attribute name
+ RETURNS
+ ID of attribute on success, negative on failure
+--------------------------------------------------------------------------*/
+hid_t
+H5Aopen_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t aapl_id, hid_t lapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *attr = NULL; /* attr token from VOL plugin */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("i", "i*s*siiii", loc_id, obj_name, attr_name, aapl_id, lapl_id,
+ rcxt_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = obj_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Create the attribute through the VOL */
+ if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, attr_name, aapl_id, dxpl_id, estack_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute")
+
+ /* Get an atom for the attribute */
+ if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ if (ret_value < 0 && attr)
+ if(H5VL_attr_close (attr, vol_plugin, H5AC_dxpl_id, estack_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aopen_by_name_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Awrite_ff
+ PURPOSE
+ Write out data to an attribute
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+herr_t
+H5Awrite_ff(hid_t attr_id, hid_t dtype_id, const void *buf, hid_t trans_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *attr;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "ii*xii", attr_id, dtype_id, buf, trans_id, estack_id);
+
+ /* check arguments */
+ if(NULL == buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (attr = (void *)H5I_object(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier")
+
+ /* write the data through the VOL */
+ if((ret_value = H5VL_attr_write(attr, vol_plugin, dtype_id, buf, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Awrite_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Aread_ff
+ PURPOSE
+ Read in data from an attribute
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+herr_t
+H5Aread_ff(hid_t attr_id, hid_t dtype_id, void *buf, hid_t rcxt_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *attr;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "ii*xii", attr_id, dtype_id, buf, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(NULL == buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (attr = (void *)H5I_object(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier")
+
+ /* Read the data through the VOL */
+ if((ret_value = H5VL_attr_read(attr, vol_plugin, dtype_id, buf, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aread_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Arename_ff
+ *
+ * Purpose: Rename an attribute
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Arename_ff(hid_t loc_id, const char *old_name, const char *new_name,
+ hid_t trans_id, hid_t estack_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "i*s*sii", loc_id, old_name, new_name, trans_id, estack_id);
+
+ /* check arguments */
+ if(!old_name || !new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil")
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+
+ /* Avoid thrashing things if the names are the same */
+ if(HDstrcmp(old_name, new_name)) {
+ H5VL_t *vol_plugin;
+ void *obj;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* rename the attribute info through the VOL */
+ if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_ATTR_RENAME, dxpl_id,
+ estack_id, old_name, new_name) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
+ }
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Arename_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Arename_by_name_ff
+ *
+ * Purpose: Rename an attribute
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Arename_by_name_ff(hid_t loc_id, const char *obj_name, const char *old_attr_name,
+ const char *new_attr_name, hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "i*s*s*siii", loc_id, obj_name, old_attr_name, new_attr_name,
+ lapl_id, trans_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
+ if(!old_attr_name || !*old_attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name")
+ if(!new_attr_name || !*new_attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ /* Avoid thrashing things if the names are the same */
+ if(HDstrcmp(old_attr_name, new_attr_name)) {
+ H5VL_t *vol_plugin;
+ void *obj;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = obj_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* rename the attribute info through the VOL */
+ if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_ATTR_RENAME, dxpl_id,
+ estack_id, old_attr_name, new_attr_name) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Arename_by_name_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Adelete_ff
+ PURPOSE
+ Deletes an attribute from a location
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+herr_t
+H5Adelete_ff(hid_t loc_id, const char *name, hid_t trans_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *obj;
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*sii", loc_id, name, trans_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
+ /* Open the attribute through the VOL */
+ if(H5VL_attr_remove(obj, loc_params, vol_plugin, name, dxpl_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Adelete_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Adelete_by_name_ff
+ PURPOSE
+ Deletes an attribute from a location
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ This function removes the named attribute from an object.
+--------------------------------------------------------------------------*/
+herr_t
+H5Adelete_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *obj;
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*s*siii", loc_id, obj_name, attr_name, lapl_id, trans_id,
+ estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = obj_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
+ /* Open the attribute through the VOL */
+ if(H5VL_attr_remove(obj, loc_params, vol_plugin, attr_name, dxpl_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Adelete_by_name_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Aexists_ff
+ *
+ * Purpose: Checks if an attribute with a given name exists on an opened
+ * object.
+ *
+ * Return: Success: Positive
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Aexists_ff(hid_t obj_id, const char *attr_name, hbool_t *ret, hid_t rcxt_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *obj;
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "i*s*bii", obj_id, attr_name, ret, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(obj_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (obj = (void *)H5VL_get_object(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(obj_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* get the attribute info through the VOL */
+ if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, dxpl_id, estack_id,
+ loc_params, attr_name, (htri_t *)ret) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aexists_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Aexists_by_name_ff
+ *
+ * Purpose: Checks if an attribute with a given name exists on an object.
+ *
+ * Return: Success: Positive
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, November 1, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Aexists_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t lapl_id, hbool_t *ret, hid_t rcxt_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin;
+ void *obj;
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "i*s*si*bii", loc_id, obj_name, attr_name, lapl_id, ret, rcxt_id,
+ estack_id);
+
+ /* check arguments */
+ if(H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
+ if(!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the dataset object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = obj_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* get the attribute info through the VOL */
+ if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, dxpl_id, estack_id,
+ loc_params, attr_name, (htri_t *)ret) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aexists_by_name_ff() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Aclose_ff
+ PURPOSE
+ Close an attribute ID
+ RETURNS
+ Non-negative on success/Negative on failure
+
+ DESCRIPTION
+ This function releases an attribute from use. Further use of the
+ attribute ID will result in undefined behavior.
+--------------------------------------------------------------------------*/
+herr_t
+H5Aclose_ff(hid_t attr_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", attr_id, estack_id);
+
+ /* check arguments */
+ if(NULL == H5I_object_verify(attr_id, H5I_ATTR))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /* Decrement references to that atom (and close it) */
+ if(H5I_dec_app_ref(attr_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aclose_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lmove_ff
+ *
+ * Purpose: Renames an object within an HDF5 file and moves it to a new
+ * group. The original name SRC is unlinked from the group graph
+ * and then inserted with the new name DST (which can specify a
+ * new path for the object) as an atomic operation. The names
+ * are interpreted relative to SRC_LOC_ID and
+ * DST_LOC_ID, which are either file IDs or group ID.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lmove_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj1 = NULL; /* object token of src_id */
+ H5VL_t *vol_plugin1; /* VOL plugin information */
+ H5VL_loc_params_t loc_params1;
+ void *obj2 = NULL; /* object token of dst_id */
+ H5VL_t *vol_plugin2; /* VOL plugin information */
+ H5VL_loc_params_t loc_params2;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*si*siiii", src_loc_id, src_name, dst_loc_id, dst_name,
+ lcpl_id, lapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC")
+ if(!src_name || !*src_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified")
+ if(!dst_name || !*dst_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
+ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
+
+ /* Check the link create property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ /* Check the link access property list */
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+
+ /* set location paramter for source object */
+ loc_params1.type = H5VL_OBJECT_BY_NAME;
+ loc_params1.loc_data.loc_by_name.name = src_name;
+ loc_params1.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params1.obj_type = H5I_get_type(src_loc_id);
+ /* set location paramter for destination object */
+ loc_params2.type = H5VL_OBJECT_BY_NAME;
+ loc_params2.loc_data.loc_by_name.name = dst_name;
+ loc_params2.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params2.obj_type = H5I_get_type(dst_loc_id);
+
+ if(H5L_SAME_LOC != src_loc_id) {
+ /* get the file object */
+ if(NULL == (obj1 = (void *)H5I_object(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ if(H5L_SAME_LOC != dst_loc_id) {
+ /* get the file object */
+ if(NULL == (obj2 = (void *)H5I_object(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ /* Make sure that the VOL plugins are the same */
+ if(H5L_SAME_LOC != dst_loc_id && H5L_SAME_LOC != src_loc_id) {
+ if (vol_plugin1->cls != vol_plugin2->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked")
+ }
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* Move the link through the VOL */
+ if((ret_value = H5VL_link_move(obj1, loc_params1, obj2, loc_params2,
+ (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2),
+ FALSE, lcpl_id, lapl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lmove_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcopy_ff
+ *
+ * Purpose: Creates an identical copy of a link with the same creation
+ * time and target. The new link can have a different name
+ * and be in a different location than the original.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcopy_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj1 = NULL; /* object token of src_id */
+ H5VL_t *vol_plugin1; /* VOL plugin information */
+ H5VL_loc_params_t loc_params1;
+ void *obj2 = NULL; /* object token of dst_id */
+ H5VL_t *vol_plugin2; /* VOL plugin information */
+ H5VL_loc_params_t loc_params2;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*si*siiii", src_loc_id, src_name, dst_loc_id, dst_name,
+ lcpl_id, lapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC")
+ if(!src_name || !*src_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified")
+ if(!dst_name || !*dst_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
+ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
+
+ /* Check the link create property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ /* Check the link access property list */
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+
+ /* set location paramter for source object */
+ loc_params1.type = H5VL_OBJECT_BY_NAME;
+ loc_params1.loc_data.loc_by_name.name = src_name;
+ loc_params1.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params1.obj_type = H5I_get_type(src_loc_id);
+ /* set location paramter for destination object */
+ loc_params2.type = H5VL_OBJECT_BY_NAME;
+ loc_params2.loc_data.loc_by_name.name = dst_name;
+ loc_params2.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params2.obj_type = H5I_get_type(dst_loc_id);
+
+ if(H5L_SAME_LOC != src_loc_id) {
+ /* get the file object */
+ if(NULL == (obj1 = (void *)H5I_object(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ if(H5L_SAME_LOC != dst_loc_id) {
+ /* get the file object */
+ if(NULL == (obj2 = (void *)H5I_object(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ /* Make sure that the VOL plugins are the same */
+ if(H5L_SAME_LOC != dst_loc_id && H5L_SAME_LOC != src_loc_id) {
+ if (vol_plugin1->cls != vol_plugin2->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked")
+ }
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* Move the link through the VOL */
+ if((ret_value = H5VL_link_move(obj1, loc_params1, obj2, loc_params2,
+ (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2),
+ TRUE, lcpl_id, lapl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lcopy_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_soft_ff
+ *
+ * Purpose: Creates a soft link from LINK_NAME to LINK_TARGET.
+ *
+ * LINK_TARGET can be anything and is interpreted at lookup
+ * time relative to the group which contains the final component
+ * of LINK_NAME. For instance, if LINK_TARGET is `./foo' and
+ * LINK_NAME is `./x/y/bar' and a request is made for `./x/y/bar'
+ * then the actual object looked up is `./x/y/./foo'.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_soft_ff(const char *link_target, hid_t link_loc_id, const char *link_name,
+ hid_t lcpl_id, hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5VL_loc_params_t loc_params;
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*si*siiii", link_target, link_loc_id, link_name, lcpl_id,
+ lapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(link_loc_id == H5L_SAME_LOC)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link location id should not be H5L_SAME_LOC")
+ if(!link_target || !*link_target)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no target specified")
+ if(!link_name || !*link_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified")
+ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ /* Check the link access property list */
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = link_name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(link_loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(link_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(link_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_LINK_TARGET_NAME, &link_target) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for target name")
+
+ /* Create the link through the VOL */
+ if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_SOFT, obj, loc_params, vol_plugin,
+ lcpl_id, lapl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lcreate_soft_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_hard_ff
+ *
+ * Purpose: Creates a hard link from NEW_NAME to CUR_NAME.
+ *
+ * CUR_NAME must name an existing object. CUR_NAME and
+ * NEW_NAME are interpreted relative to CUR_LOC_ID and
+ * NEW_LOC_ID, which are either file IDs or group IDs.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_hard_ff(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id,
+ const char *new_name, hid_t lcpl_id, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id)
+{
+ void *obj1 = NULL; /* object token of loc_id */
+ void *obj2 = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin1 = NULL; /* VOL plugin information */
+ H5VL_t *vol_plugin2 = NULL; /* VOL plugin information */
+ H5VL_loc_params_t loc_params1;
+ H5VL_loc_params_t loc_params2;
+ H5P_genplist_t *plist; /* Property list pointer */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*si*siiii", cur_loc_id, cur_name, new_loc_id, new_name,
+ lcpl_id, lapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5L_SAME_LOC")
+ if(!cur_name || !*cur_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified")
+ if(!new_name || !*new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified")
+ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
+
+ /* Check the link create property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ /* Check the link access property list */
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+
+ loc_params1.type = H5VL_OBJECT_BY_NAME;
+ loc_params1.obj_type = H5I_get_type(cur_loc_id);
+ loc_params1.loc_data.loc_by_name.name = cur_name;
+ loc_params1.loc_data.loc_by_name.plist_id = lapl_id;
+
+ loc_params2.type = H5VL_OBJECT_BY_NAME;
+ loc_params2.obj_type = H5I_get_type(new_loc_id);
+ loc_params2.loc_data.loc_by_name.name = new_name;
+ loc_params2.loc_data.loc_by_name.plist_id = lapl_id;
+
+ if(H5L_SAME_LOC != cur_loc_id) {
+ /* get the file object */
+ if(NULL == (obj1 = (void *)H5I_object(cur_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(cur_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ if(H5L_SAME_LOC != new_loc_id) {
+ /* get the file object */
+ if(NULL == (obj2 = (void *)H5I_object(new_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(new_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ /* Make sure that the VOL plugins are the same */
+ if(H5L_SAME_LOC != new_loc_id && H5L_SAME_LOC != cur_loc_id) {
+ if (vol_plugin1->cls != vol_plugin2->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked")
+ }
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_LINK_TARGET, &obj1) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id")
+ if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target name")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* Create the link through the VOL */
+ if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, obj2, loc_params2,
+ (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2),
+ lcpl_id, lapl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lcreate_hard_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ldelete_ff
+ *
+ * Purpose: Removes the specified NAME from the group graph and
+ * decrements the link count for the object to which NAME
+ * points. If the link count reaches zero then all file-space
+ * associated with the object will be reclaimed (but if the
+ * object is open, then the reclamation of the file space is
+ * delayed until all handles to the object are closed).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ldelete_ff(hid_t loc_id, const char *name, hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "i*siii", loc_id, name, lapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.obj_type = H5I_get_type(loc_id);
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Delete the link through the VOL */
+ if((ret_value = H5VL_link_remove(obj, loc_params, vol_plugin, dxpl_id,
+ estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ldelete_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lexists_ff
+ *
+ * Purpose: Checks if a link of a given name exists in a group
+ *
+ * Return: Success: Positive
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lexists_ff(hid_t loc_id, const char *name, hid_t lapl_id, hbool_t *ret,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*si*bii", loc_id, name, lapl_id, ret, rcxt_id, estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.obj_type = H5I_get_type(loc_id);
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* check link existence through the VOL */
+ if(H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_EXISTS,
+ dxpl_id, estack_id, (htri_t *)ret) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lexists_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lget_info_ff
+ *
+ * Purpose: Gets metadata for a link.
+ *
+ * Return: Success: Non-negative with information in LINFO
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lget_info_ff(hid_t loc_id, const char *name, H5L_ff_info_t *linfo ,
+ hid_t lapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*s*xiii", loc_id, name, linfo, lapl_id, rcxt_id, estack_id);
+
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.obj_type = H5I_get_type(loc_id);
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Get the link info through the VOL */
+ if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_INFO,
+ dxpl_id, estack_id, linfo)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lget_info_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lget_val_ff
+ *
+ * Purpose: Returns the link value of a link whose name is NAME. For
+ * symbolic links, this is the path to which the link points,
+ * including the null terminator. For user-defined links, it
+ * is the link buffer.
+ *
+ * At most SIZE bytes are copied to the BUF result buffer.
+ *
+ * Return: Success: Non-negative with the link value in BUF.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lget_val_ff(hid_t loc_id, const char *name, void *buf, size_t size,
+ hid_t lapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "i*s*xziii", loc_id, name, buf, size, lapl_id, rcxt_id, estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.obj_type = H5I_get_type(loc_id);
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Get the link info through the VOL */
+ if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_VAL,
+ dxpl_id, estack_id, buf, size)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lget_val_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_ff
+ *
+ * Purpose: Opens an object within an HDF5 file.
+ *
+ * This function opens an object in the same way that H5Gopen2,
+ * H5Topen2, and H5Dopen2 do. However, H5Oopen doesn't require
+ * the type of object to be known beforehand. This can be
+ * useful in user-defined links, for instance, when only a
+ * path is known.
+ *
+ * The opened object should be closed again with H5Oclose
+ * or H5Gclose, H5Tclose, or H5Dclose.
+ *
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_ff(hid_t loc_id, const char *name, hid_t lapl_id, hid_t rcxt_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5I_type_t opened_type;
+ void *opened_obj = NULL;
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("i", "i*sii", loc_id, name, lapl_id, rcxt_id);
+
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Open the object through the VOL */
+ if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type,
+ dxpl_id, H5_EVENT_STACK_NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object")
+
+ if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oopen_ff() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_token
+ *
+ * Purpose: This function retrieves a token representing an object in
+ * HDF5. This token can be used in H5Oopen_by_token(), to open the
+ * object in the same transaction it was created in. If the token
+ * buffer is NULL, the token size is returned in token_size.
+ *
+ * Return: Success: Non-negative with the link value in BUF.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_token(hid_t obj_id, void *token, size_t *token_size)
+{
+ H5VL_iod_object_t *obj = NULL; /* object token of loc_id */
+ iod_obj_id_t iod_id, mdkv_id, attrkv_id;
+ H5O_type_t type;
+ uint8_t *buf_ptr = (uint8_t *)token;
+ size_t dt_size = 0, space_size = 0;
+ H5T_t *dt = NULL;
+ H5S_t *space = NULL;
+ size_t keytype_size = 0, valtype_size;
+ H5T_t *kt = NULL, *vt = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x*z", obj_id, token, token_size);
+
+ /* get the file object */
+ if(NULL == (obj = (H5VL_iod_object_t *)H5VL_get_object(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
+
+ *token_size = sizeof(iod_obj_id_t)*3 + sizeof(H5O_type_t);
+
+ switch(obj->obj_type) {
+ case H5I_GROUP:
+ iod_id = ((const H5VL_iod_group_t *)obj)->remote_group.iod_id;
+ mdkv_id = ((const H5VL_iod_group_t *)obj)->remote_group.mdkv_id;
+ attrkv_id = ((const H5VL_iod_group_t *)obj)->remote_group.attrkv_id;
+ type = H5O_TYPE_GROUP;
+ break;
+ case H5I_DATASET:
+ {
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)obj;
+
+ iod_id = dset->remote_dset.iod_id;
+ mdkv_id = dset->remote_dset.mdkv_id;
+ attrkv_id = dset->remote_dset.attrkv_id;
+ type = H5O_TYPE_DATASET;
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(dset->remote_dset.type_id,
+ H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a datatype")
+ if(NULL == (space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a dataspace")
+
+ if(H5T_encode(dt, NULL, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+
+ if(H5S_encode(space, NULL, &space_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace")
+
+ *token_size += dt_size + space_size + sizeof(size_t)*2;
+
+ break;
+ }
+ case H5I_DATATYPE:
+ {
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)obj;
+
+ iod_id = dtype->remote_dtype.iod_id;
+ mdkv_id = dtype->remote_dtype.mdkv_id;
+ attrkv_id = dtype->remote_dtype.attrkv_id;
+ type = H5O_TYPE_NAMED_DATATYPE;
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(dtype->remote_dtype.type_id,
+ H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a datatype")
+
+ if(H5T_encode(dt, NULL, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+
+ *token_size += dt_size + sizeof(size_t);
+
+ break;
+ }
+ case H5I_MAP:
+ {
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)obj;
+
+ iod_id = map->remote_map.iod_id;
+ mdkv_id = map->remote_map.mdkv_id;
+ attrkv_id = map->remote_map.attrkv_id;
+ type = H5O_TYPE_MAP;
+
+ if(NULL == (kt = (H5T_t *)H5I_object_verify(map->remote_map.keytype_id,
+ H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a datatype")
+
+ if(H5T_encode(kt, NULL, &keytype_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+
+ if(NULL == (vt = (H5T_t *)H5I_object_verify(map->remote_map.valtype_id,
+ H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a datatype")
+
+ if(H5T_encode(vt, NULL, &valtype_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+
+ *token_size += keytype_size + valtype_size + sizeof(size_t)*2;
+
+ break;
+ }
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "bad object");
+ }
+
+ if(token) {
+ HDmemcpy(buf_ptr, &iod_id, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(buf_ptr, &mdkv_id, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(buf_ptr, &attrkv_id, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(buf_ptr, &type, sizeof(H5O_type_t));
+ buf_ptr += sizeof(H5O_type_t);
+
+ switch(obj->obj_type) {
+ case H5I_GROUP:
+ break;
+ case H5I_DATASET:
+ HDmemcpy(buf_ptr, &dt_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5T_encode(dt, buf_ptr, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+ buf_ptr += dt_size;
+
+ HDmemcpy(buf_ptr, &space_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5S_encode(space, buf_ptr, &space_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace")
+ buf_ptr += space_size;
+ break;
+ case H5I_DATATYPE:
+ HDmemcpy(buf_ptr, &dt_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5T_encode(dt, buf_ptr, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+ buf_ptr += dt_size;
+ break;
+ case H5I_MAP:
+ HDmemcpy(buf_ptr, &keytype_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5T_encode(kt, buf_ptr, &keytype_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+ buf_ptr += keytype_size;
+
+ HDmemcpy(buf_ptr, &valtype_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5T_encode(vt, buf_ptr, &valtype_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
+ buf_ptr += valtype_size;
+ break;
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "bad object");
+ }
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_by_addr_ff
+ *
+ * Purpose: This function opens an object using its address within the
+ * HDF5 file, similar to an HDF5 hard link. The open object
+ * is identical to an object opened with H5Oopen() and should
+ * be closed with H5Oclose() or a type-specific closing
+ * function (such as H5Gclose() ).
+ *
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_by_token(const void *token, hid_t trans_id, hid_t estack_id)
+{
+ H5TR_t *tr = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ H5I_type_t opened_type;
+ void *opened_obj = NULL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("i", "*xii", token, trans_id, estack_id);
+
+ if(NULL == token)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no token")
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(trans_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(NULL == (opened_obj = H5VL_iod_obj_open_token(token, tr, &opened_type, req)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object");
+
+ if(request && *req) {
+ /* insert in stack */
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+ vol_plugin->nrefs ++;
+ /* create hid_t for opened object */
+ if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize object handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oopen_by_addr_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Olink_ff
+ *
+ * Purpose: Creates a hard link from NEW_NAME to the object specified
+ * by OBJ_ID using properties defined in the Link Creation
+ * Property List LCPL.
+ *
+ * This function should be used to link objects that have just
+ * been created.
+ *
+ * NEW_NAME is interpreted relative to
+ * NEW_LOC_ID, which is either a file ID or a
+ * group ID.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Olink_ff(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj1 = NULL; /* object token of loc_id */
+ void *obj2 = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin1 = NULL; /* VOL plugin information */
+ H5VL_t *vol_plugin2 = NULL; /* VOL plugin information */
+ H5VL_loc_params_t loc_params1;
+ H5VL_loc_params_t loc_params2;
+ H5P_genplist_t *plist; /* Property list pointer */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "ii*siiii", obj_id, new_loc_id, new_name, lcpl_id, lapl_id,
+ trans_id, estack_id);
+
+ /* Check arguments */
+ if(new_loc_id == H5L_SAME_LOC)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot use H5L_SAME_LOC when only one location is specified")
+ if(!new_name || !*new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+/* Avoid compiler warning on 32-bit machines */
+#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
+ if(HDstrlen(new_name) > H5L_MAX_LINK_NAME_LEN)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "name too long")
+#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
+ if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+
+ loc_params1.type = H5VL_OBJECT_BY_SELF;
+ loc_params1.obj_type = H5I_get_type(obj_id);
+
+ loc_params2.type = H5VL_OBJECT_BY_NAME;
+ loc_params2.obj_type = H5I_get_type(new_loc_id);
+ loc_params2.loc_data.loc_by_name.name = new_name;
+ loc_params2.loc_data.loc_by_name.plist_id = lapl_id;
+
+ if(H5L_SAME_LOC != obj_id) {
+ /* get the file object */
+ if(NULL == (obj1 = (void *)H5VL_get_object(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ if(H5L_SAME_LOC != new_loc_id) {
+ /* get the file object */
+ if(NULL == (obj2 = (void *)H5VL_get_object(new_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(new_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ }
+ /* Make sure that the VOL plugins are the same */
+ if(H5L_SAME_LOC != new_loc_id && H5L_SAME_LOC != obj_id) {
+ if (vol_plugin1->cls != vol_plugin2->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked")
+ }
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* set creation properties */
+ if(H5P_set(plist, H5VL_LINK_TARGET, &obj1) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id")
+ if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* Create the link through the VOL */
+ if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, obj2, loc_params2,
+ (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2),
+ lcpl_id, lapl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Olink_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oexists_by_name_ff
+ *
+ * Purpose: Determine if a linked-to object exists
+ *
+ * Return: Success: TRUE/FALSE
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oexists_by_name_ff(hid_t loc_id, const char *name, hbool_t *ret, hid_t lapl_id,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*s*biii", loc_id, name, ret, lapl_id, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* change the ref count through the VOL */
+ if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_EXISTS,
+ dxpl_id, estack_id, (htri_t *)ret) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name)
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oexists_by_name_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oset_comment_ff
+ *
+ * Purpose: Gives the specified object a comment. The COMMENT string
+ * should be a null terminated string. An object can have only
+ * one comment at a time. Passing NULL for the COMMENT argument
+ * will remove the comment property from the object.
+ *
+ * Note: Deprecated in favor of using attributes on objects
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oset_comment_ff(hid_t obj_id, const char *comment, hid_t trans_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*sii", obj_id, comment, trans_id, estack_id);
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(obj_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* set comment on object through the VOL */
+ if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_SET_COMMENT,
+ dxpl_id, estack_id, comment) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oset_comment_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oset_comment_by_name_ff
+ *
+ * Purpose: Gives the specified object a comment. The COMMENT string
+ * should be a null terminated string. An object can have only
+ * one comment at a time. Passing NULL for the COMMENT argument
+ * will remove the comment property from the object.
+ *
+ * Note: Deprecated in favor of using attributes on objects
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oset_comment_by_name_ff(hid_t loc_id, const char *name, const char *comment,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*s*siii", loc_id, name, comment, lapl_id, trans_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* set comment on object through the VOL */
+ if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_SET_COMMENT,
+ dxpl_id, estack_id, comment) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oset_comment_by_name_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_comment_ff
+ *
+ * Purpose: Retrieve comment for an object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_comment_ff(hid_t loc_id, char *comment, size_t bufsize, ssize_t *ret,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*sz*Zsii", loc_id, comment, bufsize, ret, rcxt_id, estack_id);
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_COMMENT,
+ dxpl_id, estack_id, comment, bufsize, ret) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object comment")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_comment_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_comment_by_name_ff
+ *
+ * Purpose: Retrieve comment for an object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_comment_by_name_ff(hid_t loc_id, const char *name, char *comment, size_t bufsize,
+ ssize_t *ret, hid_t lapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*s*sz*Zsiii", loc_id, name, comment, bufsize, ret, lapl_id,
+ rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_COMMENT,
+ dxpl_id, estack_id, comment, bufsize, ret) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_comment_by_name_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ocopy_ff
+ *
+ * Purpose: Copy an object (group or dataset) to destination location
+ * within a file or cross files. PLIST_ID is a property list
+ * which is used to pass user options and properties to the
+ * copy. The name, dst_name, must not already be taken by some
+ * other object in the destination group.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ocopy_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id,
+ hid_t trans_id, hid_t estack_id)
+{
+ void *obj1 = NULL; /* object token of src_id */
+ H5VL_t *vol_plugin1; /* VOL plugin information */
+ H5VL_loc_params_t loc_params1;
+ void *obj2 = NULL; /* object token of dst_id */
+ H5VL_t *vol_plugin2; /* VOL plugin information */
+ H5VL_loc_params_t loc_params2;
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "i*si*siiii", src_loc_id, src_name, dst_loc_id, dst_name,
+ ocpypl_id, lcpl_id, trans_id, estack_id);
+
+ /* Get correct property lists */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Get object copy property list */
+ if(H5P_DEFAULT == ocpypl_id)
+ ocpypl_id = H5P_OBJECT_COPY_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list")
+
+ /* get the object */
+ if(NULL == (obj1 = (void *)H5I_object(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src ID does not contain VOL information")
+ loc_params1.type = H5VL_OBJECT_BY_SELF;
+ loc_params1.obj_type = H5I_get_type(src_loc_id);
+
+ /* get the object */
+ if(NULL == (obj2 = (void *)H5I_object(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst ID does not contain VOL information")
+ loc_params2.type = H5VL_OBJECT_BY_SELF;
+ loc_params2.obj_type = H5I_get_type(dst_loc_id);
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* Open the object through the VOL */
+ if((ret_value = H5VL_object_copy(obj1, loc_params1, vol_plugin1, src_name,
+ obj2, loc_params2, vol_plugin2, dst_name,
+ ocpypl_id, lcpl_id, dxpl_id, estack_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ocopy_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_info_ff
+ *
+ * Purpose: Retrieve information about an object.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_info_ff(hid_t loc_id, H5O_ff_info_t *oinfo, hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*xii", loc_id, oinfo, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!oinfo)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Get the group info through the VOL using the location token */
+ if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO,
+ dxpl_id, estack_id, oinfo)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_info_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_info_by_name_ff
+ *
+ * Purpose: Retrieve information about an object.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_info_by_name_ff(hid_t loc_id, const char *name, H5O_ff_info_t *oinfo,
+ hid_t lapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ hid_t dxpl_id = H5P_DATASET_XFER_DEFAULT; /* transfer property list to pass to the VOL plugin */
+ H5P_genplist_t *plist ; /* Property list pointer */
+ H5VL_loc_params_t loc_params;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*s*xiii", loc_id, name, oinfo, lapl_id, rcxt_id, estack_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ if(!oinfo)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
+ if(H5P_DEFAULT == lapl_id)
+ lapl_id = H5P_LINK_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
+
+ loc_params.type = H5VL_OBJECT_BY_NAME;
+ loc_params.loc_data.loc_by_name.name = name;
+ loc_params.loc_data.loc_by_name.plist_id = lapl_id;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the file object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* Get the group info through the VOL using the location token */
+ if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO,
+ dxpl_id, estack_id, oinfo)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_info_by_name_ff() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oclose_ff
+ *
+ * Purpose: Close an open file object.
+ *
+ * This is the companion to H5Oopen. It is used to close any
+ * open object in an HDF5 file (but not IDs are that not file
+ * objects, such as property lists and dataspaces). It has
+ * the same effect as calling H5Gclose, H5Dclose, or H5Tclose.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oclose_ff(hid_t object_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", object_id, estack_id);
+
+ /* Get the type of the object and close it in the correct way */
+ switch(H5I_get_type(object_id)) {
+ case H5I_GROUP:
+ case H5I_DATATYPE:
+ case H5I_DATASET:
+ case H5I_MAP:
+ /* check ID */
+ if(H5I_object(object_id) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object");
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(object_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ if(H5I_dec_app_ref(object_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object");
+ break;
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)")
+ break;
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oclose_ff() */
+
+herr_t
+H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension,
+ hid_t memtype, const void *buf)
+{
+ hsize_t size[H5S_MAX_RANK];
+ hsize_t start[H5S_MAX_RANK];
+ hsize_t count[H5S_MAX_RANK];
+ hsize_t stride[H5S_MAX_RANK];
+ hsize_t block[H5S_MAX_RANK];
+ hsize_t old_size=0; /* the size of the dimension to be extended */
+ int ndims, i; /* number of dimensions in dataspace */
+ hid_t space_id = FAIL; /* old File space */
+ hid_t new_space_id = FAIL; /* new file space (after extension) */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts; /* number of elements in selection */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "iiIuzi*x", dset_id, dxpl_id, axis, extension, memtype, buf);
+
+ /* check arguments */
+ if(H5I_DATASET != H5I_get_type(dset_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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 dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* get the rank of this dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ if((int)axis >= ndims)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Invalid axis");
+
+ /* get the dimensions sizes of the dataspace */
+ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion sizes");
+
+ /* adjust the dimension size of the requested dimension,
+ but first record the old dimension size */
+ old_size = size[axis];
+ size[axis] += extension;
+ if(extension < old_size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "extend size is smaller than current size of axis");
+
+ /* set the extent of the dataset to the new dimension */
+ if(H5Dset_extent(dset_id, size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset");
+
+ /* get the new dataspace of the dataset */
+ if(FAIL == (new_space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* select a hyperslab corresponding to the append operation */
+ for(i=0 ; i<ndims ; i++) {
+ start[i] = 0;
+ stride[i] = 1;
+ count[i] = size[i];
+ block[i] = 1;
+ if(i == (int)axis) {
+ count[i] = extension;
+ start[i] = old_size;
+ }
+ }
+ if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ nelmts = H5Sget_select_npoints(new_space_id);
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close new dataspace */
+ if(new_space_id != FAIL && H5Sclose(new_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOappend */
+
+herr_t
+H5DOsequence(hid_t dset_id, hid_t dxpl_id, unsigned axis, hsize_t start_off,
+ size_t sequence, hid_t memtype, void *buf)
+{
+ hsize_t size[H5S_MAX_RANK];
+ hsize_t start[H5S_MAX_RANK];
+ hsize_t count[H5S_MAX_RANK];
+ hsize_t stride[H5S_MAX_RANK];
+ hsize_t block[H5S_MAX_RANK];
+ int ndims, i; /* number of dimensions in dataspace */
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts; /* number of elements in selection */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "iiIuhzi*x", dset_id, dxpl_id, axis, start_off, sequence, memtype,
+ buf);
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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 dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* get the rank of this dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ if((int)axis >= ndims)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Invalid axis");
+
+ /* get the dimensions sizes of the dataspace */
+ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion sizes");
+
+ /* select a hyperslab corresponding to the append operation */
+ for(i=0 ; i<ndims ; i++) {
+ start[i] = 0;
+ stride[i] = 1;
+ count[i] = size[i];
+ block[i] = 1;
+ if(i == (int)axis) {
+ count[i] = sequence;
+ start[i] = start_off;
+ }
+ }
+ if(FAIL == H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+
+ nelmts = H5Sget_select_npoints(space_id);
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Read the data */
+ if(H5Dread(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOsequence */
+
+herr_t H5DOset(hid_t dset_id, hid_t dxpl_id, const hsize_t coord[],
+ hid_t memtype, const void *buf)
+{
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts = 1;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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 dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ if(FAIL == H5Sselect_elements(space_id, H5S_SELECT_SET, (size_t)nelmts, coord))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dwrite(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOset */
+
+herr_t H5DOget(hid_t dset_id, hid_t dxpl_id, const hsize_t coord[],
+ hid_t memtype, void *buf)
+{
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts = 1;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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 dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ if(FAIL == H5Sselect_elements(space_id, H5S_SELECT_SET, (size_t)nelmts, coord))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dread(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOget */
+
+
+herr_t H5DOappend_ff(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension,
+ hid_t memtype, const void *buf, hid_t trans_id, hid_t estack_id)
+{
+ hsize_t size[H5S_MAX_RANK];
+ hsize_t start[H5S_MAX_RANK];
+ hsize_t count[H5S_MAX_RANK];
+ hsize_t stride[H5S_MAX_RANK];
+ hsize_t block[H5S_MAX_RANK];
+ hsize_t old_size=0; /* the size of the dimension to be extended */
+ int ndims, i; /* number of dimensions in dataspace */
+ hid_t space_id = FAIL; /* old File space */
+ hid_t new_space_id = FAIL; /* new file space (after extension) */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts; /* number of elements in selection */
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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");
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* get the rank of this dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ if((int)axis >= ndims)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Invalid axis");
+
+ /* get the dimensions sizes of the dataspace */
+ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion sizes");
+
+ /* adjust the dimension size of the requested dimension,
+ but first record the old dimension size */
+ old_size = size[axis];
+ size[axis] += extension;
+ if(extension < old_size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "extend size is smaller than current size of axis");
+
+ /* set the extent of the dataset to the new dimension */
+ if(H5Dset_extent_ff(dset_id, size, trans_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset");
+
+ /* get the new dataspace of the dataset */
+ if(FAIL == (new_space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* select a hyperslab corresponding to the append operation */
+ for(i=0 ; i<ndims ; i++) {
+ start[i] = 0;
+ stride[i] = 1;
+ count[i] = size[i];
+ block[i] = 1;
+ if(i == (int)axis) {
+ count[i] = extension;
+ start[i] = old_size;
+ }
+ }
+ if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ nelmts = H5Sget_select_npoints(new_space_id);
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dwrite_ff(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf, trans_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close new dataspace */
+ if(new_space_id != FAIL && H5Sclose(new_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOappend_ff */
+
+herr_t
+H5DOsequence_ff(hid_t dset_id, hid_t dxpl_id, unsigned axis, hsize_t start_off,
+ size_t sequence, hid_t memtype, void *buf, hid_t rcxt_id, hid_t estack_id)
+{
+ hsize_t size[H5S_MAX_RANK];
+ hsize_t start[H5S_MAX_RANK];
+ hsize_t count[H5S_MAX_RANK];
+ hsize_t stride[H5S_MAX_RANK];
+ hsize_t block[H5S_MAX_RANK];
+ int ndims, i; /* number of dimensions in dataspace */
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts; /* number of elements in selection */
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "iiIuhzi*xii", dset_id, dxpl_id, axis, start_off, sequence,
+ memtype, buf, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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");
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* get the dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ /* get the rank of this dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ if((int)axis >= ndims)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Invalid axis");
+
+ /* get the dimensions sizes of the dataspace */
+ if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion sizes");
+
+ /* select a hyperslab corresponding to the append operation */
+ for(i=0 ; i<ndims ; i++) {
+ start[i] = 0;
+ stride[i] = 1;
+ count[i] = size[i];
+ block[i] = 1;
+ if(i == (int)axis) {
+ count[i] = sequence;
+ start[i] = start_off;
+ }
+ }
+ if(FAIL == H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ nelmts = H5Sget_select_npoints(space_id);
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Read the data */
+ if(H5Dread_ff(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf, rcxt_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOsequence_ff */
+
+herr_t H5DOset_ff(hid_t dset_id, hid_t dxpl_id, const hsize_t coord[],
+ hid_t memtype, const void *buf, hid_t trans_id, hid_t estack_id)
+{
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts = 1;
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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");
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for trans_id")
+
+ /* get the dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ if(FAIL == H5Sselect_elements(space_id, H5S_SELECT_SET, (size_t)nelmts, coord))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dwrite_ff(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf, trans_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOset_ff */
+
+herr_t H5DOget_ff(hid_t dset_id, hid_t dxpl_id, const hsize_t coord[],
+ hid_t memtype, void *buf, hid_t rcxt_id, hid_t estack_id)
+{
+ hid_t space_id = FAIL; /* old File space */
+ hid_t mem_space_id = FAIL; /* memory space for data buffer */
+ hsize_t nelmts = 1;
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* check arguments */
+ if(!dset_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* 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");
+
+ /* store the transaction ID in the dxpl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_set(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rcxt_id")
+
+ /* get the dataspace of the dataset */
+ if(FAIL == (space_id = H5Dget_space(dset_id)))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace");
+
+ if(FAIL == H5Sselect_elements(space_id, H5S_SELECT_SET, (size_t)nelmts, coord))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTSET, FAIL, "unable to set selection in dataspace");
+
+ /* create a memory space */
+ mem_space_id = H5Screate_simple(1, &nelmts, NULL);
+
+ /* Write the data */
+ if(H5Dread_ff(dset_id, memtype, mem_space_id, space_id, dxpl_id, buf, rcxt_id, estack_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+done:
+
+ /* close old dataspace */
+ if(space_id != FAIL && H5Sclose(space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ /* close memory dataspace */
+ if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "unable to close dataspace")
+
+ FUNC_LEAVE_API(ret_value)
+}/* end H5DOget_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dprefetch
+ *
+ * Purpose: Prefetched a Dataset from Central Storage to Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Dprefetch(hid_t dset_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t dapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *dset = NULL; /* pointer to dset object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (dset = (void *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_prefetch(dset, rcxt_id, replica_id, dapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't prefetch dataset")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dprefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Devict
+ *
+ * Purpose: Evicts a Dataset from Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Devict(hid_t dset_id, uint64_t c_version, hid_t dapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generated request pointer */
+ void *dset = NULL; /* pointer to dset object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (dset = (void *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_evict(dset, c_version, dapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't evict dataset")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Devict() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gprefetch
+ *
+ * Purpose: Prefetched a Group from Central Storage to Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Gprefetch(hid_t grp_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t gapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *grp = NULL; /* pointer to grp object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (grp = (void *)H5I_object_verify(grp_id, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(grp_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_prefetch(grp, rcxt_id, replica_id, gapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't prefetch group")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gprefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gevict
+ *
+ * Purpose: Evicts a Group from Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Gevict(hid_t grp_id, uint64_t c_version, hid_t gapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generated request pointer */
+ void *grp = NULL; /* pointer to grp object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (grp = (void *)H5I_object_verify(grp_id, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(grp_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_evict(grp, c_version, gapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't evict group")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gevict() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tprefetch
+ *
+ * Purpose: Prefetched a Datatype from Central Storage to Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Tprefetch(hid_t dtype_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t tapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *dtype = NULL; /* pointer to dtype object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ H5T_t *type; /* Datatype object for ID */
+ htri_t status; /* Generic status value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check arguments */
+ if(NULL == (type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ /* Check if the datatype is committed */
+ if((status = H5T_committed(type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check whether datatype is committed")
+
+ if(FALSE == status) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't prefetch a non committed datatype");
+ }
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tapl_id)
+ tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dtype_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* get the named datatype object */
+ if(NULL == (dtype = H5VL_get_object(dtype_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_prefetch(dtype, rcxt_id, replica_id, tapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't prefetch datatype")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tprefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tevict
+ *
+ * Purpose: Evicts a Datatype from Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Tevict(hid_t dtype_id, uint64_t c_version, hid_t tapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *dtype = NULL; /* pointer to dtype object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ H5T_t *type; /* Datatype object for ID */
+ htri_t status; /* Generic status value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check arguments */
+ if(NULL == (type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ /* Check if the datatype is committed */
+ if((status = H5T_committed(type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check whether datatype is committed")
+
+ if(FALSE == status) {
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't prefetch a non committed datatype");
+ }
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tapl_id)
+ tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dtype_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* get the named datatype object */
+ if(NULL == (dtype = H5VL_get_object(dtype_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_evict(dtype, c_version, tapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't evict datatype")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tevict() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5FFprivate.h b/src/H5FFprivate.h
new file mode 100644
index 0000000..081ccca
--- /dev/null
+++ b/src/H5FFprivate.h
@@ -0,0 +1,60 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 private information about the H5FF module
+ */
+#ifndef _H5FFprivate_H
+#define _H5FFprivate_H
+
+/* Include package's public header */
+#include "H5FFpublic.h"
+
+/* Private headers needed by this file */
+#include "H5private.h" /* Generic Functions */
+
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/* DXPL property to store the transaction ID from the FF wrappers */
+#define H5VL_TRANS_ID "transaction_id"
+
+/* DXPL property to store the read context ID from the FF wrappers */
+#define H5VL_CONTEXT_ID "read_context_id"
+
+/* property to tell the VOL plugin to acquire a read context on the
+ container when the file is opened */
+#define H5VL_ACQUIRE_RC_ID "acquire_version"
+
+/* property to determine the scope of data integrity checks in the FF stack */
+#define H5VL_CS_BITFLAG_NAME "checksum_bitflag"
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+
+#endif /* _H5FFprivate_H */
+
diff --git a/src/H5FFpublic.h b/src/H5FFpublic.h
new file mode 100644
index 0000000..083409d
--- /dev/null
+++ b/src/H5FFpublic.h
@@ -0,0 +1,226 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+ * H5FF module.
+ */
+#ifndef _H5FFpublic_H
+#define _H5FFpublic_H
+
+/* System headers needed by this file */
+
+/* Public headers needed by this file */
+#include "H5VLpublic.h" /* Public VOL header file */
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef H5_HAVE_EFF
+
+typedef uint64_t haddr_ff_t;
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+typedef struct H5L_ff_info_t{
+ H5L_type_t type;
+ H5T_cset_t cset;
+ union {
+ haddr_ff_t address;
+ size_t val_size;
+ } u;
+} H5L_ff_info_t;
+
+typedef struct H5O_ff_info_t {
+ haddr_ff_t addr; /* Object address in file */
+ H5O_type_t type; /* Basic object type */
+ unsigned rc; /* Reference count of object */
+ hsize_t num_attrs; /* # of attributes attached to object */
+} H5O_ff_info_t;
+
+/* Bitflag values to enable/disable checksuming in different layers */
+typedef enum H5FF_checksum_bitflag_t {
+ H5_CHECKSUM_NONE = 0x00,
+ H5_CHECKSUM_TRANSFER = 0x01,
+ H5_CHECKSUM_IOD = 0x02,
+ H5_CHECKSUM_MEMORY = 0x04,
+ H5_CHECKSUM_ALL = 0x07
+} H5FF_checksum_bitflag_t;
+
+/********************/
+/* Public Variables */
+/********************/
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+/* API wrappers */
+H5_DLL hid_t H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl,
+ hid_t fapl, hid_t estack_id);
+H5_DLL hid_t H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id,
+ hid_t *rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Fclose_ff(hid_t file_id, hid_t estack_id);
+
+H5_DLL hid_t H5Gcreate_ff(hid_t loc_id, const char *name, hid_t lcpl_id,
+ hid_t gcpl_id, hid_t gapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Gopen_ff(hid_t loc_id, const char *name, hid_t gapl_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Gclose_ff(hid_t group_id, hid_t estack_id);
+
+H5_DLL hid_t H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id,
+ hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Dwrite_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, const void *buf,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Dread_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, void *buf/*out*/,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Dset_extent_ff(hid_t dset_id, const hsize_t size[], hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Dclose_ff(hid_t dset_id, hid_t estack_id);
+
+H5_DLL herr_t H5Tcommit_ff(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id,
+ hid_t tcpl_id, hid_t tapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Topen_ff(hid_t loc_id, const char *name, hid_t tapl_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Tclose_ff(hid_t type_id, hid_t estack_id);
+
+H5_DLL hid_t H5Acreate_ff(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
+ hid_t acpl_id, hid_t aapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Acreate_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Aopen_ff(hid_t loc_id, const char *attr_name, hid_t aapl_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL hid_t H5Aopen_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t aapl_id, hid_t lapl_id, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Awrite_ff(hid_t attr_id, hid_t dtype_id, const void *buf,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Aread_ff(hid_t attr_id, hid_t dtype_id, void *buf, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Arename_ff(hid_t loc_id, const char *old_name, const char *new_name,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Arename_by_name_ff(hid_t loc_id, const char *obj_name, const char *old_attr_name,
+ const char *new_attr_name, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Adelete_ff(hid_t loc_id, const char *name, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Adelete_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Aexists_by_name_ff(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t lapl_id, hbool_t *ret, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Aexists_ff(hid_t obj_id, const char *attr_name, hbool_t *ret,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Aclose_ff(hid_t attr_id, hid_t estack_id);
+
+H5_DLL herr_t H5Lmove_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Lcopy_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Lcreate_soft_ff(const char *link_target, hid_t link_loc_id, const char *link_name,
+ hid_t lcpl_id, hid_t lapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Lcreate_hard_ff(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id,
+ const char *new_name, hid_t lcpl_id, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Ldelete_ff(hid_t loc_id, const char *name, hid_t lapl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Lexists_ff(hid_t loc_id, const char *name, hid_t lapl_id, hbool_t *ret,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Lget_info_ff(hid_t link_loc_id, const char *link_name, H5L_ff_info_t *link_buff,
+ hid_t lapl_id, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Lget_val_ff(hid_t link_loc_id, const char *link_name, void *linkval_buff,
+ size_t size, hid_t lapl_id, hid_t rcxt_id, hid_t estack_id);
+
+H5_DLL hid_t H5Oopen_ff(hid_t loc_id, const char *name, hid_t lapl_id,
+ hid_t rcxt_id);
+H5_DLL herr_t H5Oget_token(hid_t obj_id, void *token, size_t *token_size);
+H5_DLL hid_t H5Oopen_by_token(const void *token, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Olink_ff(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Oexists_by_name_ff(hid_t loc_id, const char *name, hbool_t *ret,
+ hid_t lapl_id, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Oset_comment_ff(hid_t obj_id, const char *comment, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Oset_comment_by_name_ff(hid_t loc_id, const char *name, const char *comment,
+ hid_t lapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Oget_comment_ff(hid_t loc_id, char *comment, size_t bufsize, ssize_t *ret,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Oget_comment_by_name_ff(hid_t loc_id, const char *name, char *comment, size_t bufsize,
+ ssize_t *ret, hid_t lapl_id, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Ocopy_ff(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Oget_info_ff(hid_t object_id, H5O_ff_info_t *object_info,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Oget_info_by_name_ff(hid_t loc_id, const char *object_name,
+ H5O_ff_info_t *object_info, hid_t lapl_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Oclose_ff(hid_t object_id, hid_t estack_id);
+
+#if 0
+H5_DLL herr_t H5Aprefetch(hid_t attr_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t aapl_id, hid_t estack_id);
+H5_DLL herr_t H5Aevict(hid_t attr_id, uint64_t c_version, hid_t aapl_id, hid_t estack_id);
+#endif
+
+H5_DLL herr_t H5Gprefetch(hid_t grp_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t gapl_id, hid_t estack_id);
+H5_DLL herr_t H5Tprefetch(hid_t type_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t tapl_id, hid_t estack_id);
+H5_DLL herr_t H5Dprefetch(hid_t dset_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t dapl_id, hid_t estack_id);
+H5_DLL herr_t H5Mprefetch(hid_t map_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t mapl_id, hid_t estack_id);
+
+H5_DLL herr_t H5Devict(hid_t dset_id, uint64_t c_version, hid_t dapl_id, hid_t estack_id);
+H5_DLL herr_t H5Mevict(hid_t map_id, uint64_t c_version, hid_t mapl_id, hid_t estack_id);
+H5_DLL herr_t H5Gevict(hid_t grp_id, uint64_t c_version, hid_t gapl_id, hid_t estack_id);
+H5_DLL herr_t H5Tevict(hid_t type_id, uint64_t c_version, hid_t tapl_id, hid_t estack_id);
+
+/* New Routines for Dynamic Data Structures Use Case (ACG) */
+H5_DLL herr_t H5DOappend(hid_t dataset_id, hid_t dxpl_id, unsigned axis, size_t extension,
+ hid_t memtype, const void *buffer);
+H5_DLL herr_t H5DOappend_ff(hid_t dataset_id, hid_t dxpl_id, unsigned axis, size_t extension,
+ hid_t memtype, const void *buffer, hid_t trans_id,
+ hid_t estack_id);
+H5_DLL herr_t H5DOsequence(hid_t dataset_id, hid_t dxpl_id, unsigned axis, hsize_t start,
+ size_t sequence, hid_t memtype, void *buffer);
+H5_DLL herr_t H5DOsequence_ff(hid_t dataset_id, hid_t dxpl_id, unsigned axis, hsize_t start,
+ size_t sequence, hid_t memtype, void *buffer,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5DOset(hid_t dataset_id, hid_t dxpl_id, const hsize_t coord[],
+ hid_t memtype, const void *buffer);
+H5_DLL herr_t H5DOset_ff(hid_t dataset_id, hid_t dxpl_id, const hsize_t coord[],hid_t memtype,
+ const void *buffer, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5DOget(hid_t dataset_id, hid_t dxpl_id, const hsize_t coord[],hid_t memtype, void *buffer);
+H5_DLL herr_t H5DOget_ff(hid_t dataset_id, hid_t dxpl_id, const hsize_t coord[],hid_t memtype,
+ void *buffer, hid_t rcxt_id, hid_t estack_id);
+
+#endif /* H5_HAVE_EFF */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _H5FFpublic_H */
+
diff --git a/src/H5FLprivate.h b/src/H5FLprivate.h
index 556712f..d149306 100644
--- a/src/H5FLprivate.h
+++ b/src/H5FLprivate.h
@@ -36,7 +36,7 @@
/* Private headers needed by this file */
/* Macros for turning off free lists in the library */
-/*#define H5_NO_FREE_LISTS*/
+#define H5_NO_FREE_LISTS
#if defined H5_NO_FREE_LISTS || defined H5_USING_MEMCHECKER
#define H5_NO_REG_FREE_LISTS
#define H5_NO_ARR_FREE_LISTS
diff --git a/src/H5G.c b/src/H5G.c
index 62c9235..30894ea 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -324,7 +324,8 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t g
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
/* Create the group through the VOL */
- if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, name, gcpl_id, gapl_id, H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
+ if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, name, gcpl_id, gapl_id,
+ H5AC_dxpl_id, H5_EVENT_STACK_NULL)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
/* Get an atom for the group */
@@ -728,6 +729,7 @@ done:
herr_t
H5Gclose(hid_t group_id)
{
+ H5VL_t *vol_plugin = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -737,6 +739,13 @@ H5Gclose(hid_t group_id)
if(NULL == H5I_object_verify(group_id,H5I_GROUP))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(group_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = H5_EVENT_STACK_NULL;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
/*
* Decrement the counter on the group atom. It will be freed if the count
* reaches zero.
@@ -776,7 +785,8 @@ H5G_close_group(void *grp, H5VL_t *vol_plugin)
FUNC_ENTER_NOAPI_NOINIT
/* Close the group through the VOL*/
- if((ret_value = H5VL_group_close(grp, vol_plugin, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_group_close(grp, vol_plugin, vol_plugin->close_dxpl_id,
+ vol_plugin->close_estack_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group")
done:
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
index 2a83f15..0239c92 100644
--- a/src/H5Gloc.c
+++ b/src/H5Gloc.c
@@ -180,7 +180,7 @@ H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc)
/* Get the actual datatype object if the VOL object is set */
if(NULL == (dt = (H5T_t *)H5T_get_named_type((const H5T_t *)obj)))
dt = (H5T_t *) obj;
-
+
if(NULL == (loc->oloc = H5T_oloc(dt)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype")
if(NULL == (loc->path = H5T_nameof(dt)))
diff --git a/src/H5I.c b/src/H5I.c
index 5c6aca6..6a93c4c 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -52,6 +52,7 @@
#include "H5SLprivate.h" /* Skip Lists */
#include "H5Tprivate.h" /* Datatypes */
#include "H5VLprivate.h" /* Virtual Object Layer */
+#include "H5VLiod_client.h" /* Client IOD helper */
#include "H5Fpkg.h" /* MSC- just a temp workaround FILES*/
@@ -2147,6 +2148,7 @@ H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data)
herr_t ret_value; /* Return value */
FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "Itx*x", type, op, op_data);
/* Set up udata struct */
int_udata.op = op;
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 4c3457c..325643a 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -89,5 +89,6 @@ H5_DLL herr_t H5I_dec_type_ref(H5I_type_t type);
H5_DLL herr_t H5I_register_aux(hid_t id, void *aux_ptr);
H5_DLL void *H5I_get_aux(hid_t id);
H5_DLL hid_t H5I_get_id(void *object, H5I_type_t type);
+
#endif /* _H5Iprivate_H */
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 0df96f1..309892c 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 */
@@ -45,6 +46,11 @@ typedef enum H5I_type_t {
H5I_REFERENCE, /*type ID for Reference objects */
H5I_VFL, /*type ID for virtual file layer */
H5I_VOL, /*type ID for virtual object layer */
+ H5I_ES, /*type ID for Event Queue objects */
+ H5I_RC, /*type ID for Read Context objects */
+ H5I_TR, /*type ID for Transaction objects */
+ H5I_QUERY, /*type ID for Query objects */
+ H5I_VIEW, /*type ID for view objects */
H5I_GENPROP_CLS, /*type ID for generic property list classes */
H5I_GENPROP_LST, /*type ID for generic property lists */
H5I_ERROR_CLASS, /*type ID for error classes */
diff --git a/src/H5M.c b/src/H5M.c
new file mode 100644
index 0000000..70f2d6c
--- /dev/null
+++ b/src/H5M.c
@@ -0,0 +1,1073 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5M_init_interface
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod_client.h" /* IOD VOL plugin */
+
+#ifdef H5_HAVE_EFF
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+static herr_t H5M_close_map(void *map, H5VL_t *vol_plugin);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* 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 */
+ NULL, /* Callback routine for closing objects of this class */
+ (H5I_free2_t)H5M_close_map /* Callback routine for closing auxilary objects of this class */
+}};
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+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() */
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5M_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5M_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5M_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Create attribute ID type.
+ */
+ if(H5I_register_type(H5I_MAP_CLS) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M_init_interface() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5M_term_interface
+ PURPOSE
+ Terminate various H5M objects
+ USAGE
+ void H5M_term_interface()
+ RETURNS
+ DESCRIPTION
+ Release any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5M_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_interface_initialize_g) {
+ if((n = H5I_nmembers(H5I_MAP))>0) {
+ (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
+ } else {
+ (void)H5I_dec_type_ref(H5I_MAP);
+ H5_interface_initialize_g = 0;
+ n = 1;
+ }
+ }
+ FUNC_LEAVE_NOAPI(n)
+} /* H5M_term_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mcreate_ff
+ *
+ * Purpose:
+ * The H5Mcreate routine creates a new map object named name
+ * at the location given by loc_id. Map creation and access property
+ * lists (mcpl_id and mapl_id) modify the new map objectÕs behavior.
+ * All keys for the map are of keytype datatype and all values for the
+ * map are of valtype datatype. The H5Mcreate_ff routine is identical
+ * in functionality, but allows for asynchronous operation and
+ * inclusion in a transaction. Map IDs returned from this routine
+ * must be released with H5Mclose.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mcreate_ff(hid_t loc_id, const char *name, hid_t keytype, hid_t valtype,
+ hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, hid_t trans_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("i", "i*siiiiiii", loc_id, name, keytype, valtype, lcpl_id, mcpl_id,
+ mapl_id, trans_id, estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Check map 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 group create property list")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == mapl_id)
+ mapl_id = H5P_MAP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(mapl_id, H5P_MAP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object/file identifier")
+ /* get the plugin pointer */
+ if(NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ if(vol_plugin->cls->value != IOD)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "only IOD plugin supports MAP objects")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* call the IOD specific private routine to create a map object */
+ if(NULL == (map = H5VL_iod_map_create(obj, loc_params, name, keytype, valtype,
+ lcpl_id, mcpl_id, mapl_id, trans_id, req)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create map")
+
+ /* increment the ref count on the VOL plugin */
+ vol_plugin->nrefs ++;
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack")
+ }
+
+ /* Get an atom for the map */
+ if((ret_value = H5I_register2(H5I_MAP, map, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize map handle")
+
+done:
+ if (ret_value < 0 && map)
+ if(H5VL_iod_map_close (map, req) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release map")
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mcreate_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mopen_ff
+ *
+ * Purpose:
+ * The H5Mopen routine opens an existing map object named
+ * name at the location given by loc_id. The map access property list
+ * (mapl_id) modifies the map objectÕs behavior. The H5Mopen_ff
+ * routine is identical in functionality, but allows for asynchronous
+ * operation and inclusion in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mopen_ff(hid_t loc_id, const char *name, hid_t mapl_id, hid_t rcxt_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ void *obj = NULL; /* object token of loc_id */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("i", "i*siii", loc_id, name, mapl_id, rcxt_id, estack_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == mapl_id)
+ mapl_id = H5P_MAP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(mapl_id, H5P_MAP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the object */
+ if(NULL == (obj = (void *)H5VL_get_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object/file identifier")
+ /* get the plugin pointer */
+ if(NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(vol_plugin->cls->value != IOD)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "only IOD plugin supports MAP objects");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* call the IOD specific private routine to create a map object */
+ if(NULL == (map = H5VL_iod_map_open(obj, loc_params, name, mapl_id, rcxt_id, req)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create map")
+
+ /* increment the ref count on the VOL plugin */
+ vol_plugin->nrefs ++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack")
+ }
+
+ /* Get an atom for the map */
+ if((ret_value = H5I_register2(H5I_MAP, map, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize map handle")
+
+done:
+ if (ret_value < 0 && map)
+ if(H5VL_iod_map_close (map, req) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release map")
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mopen_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mset_ff
+ *
+ * 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. The data transfer property
+ * list (dxpl_id) may modify the operationÕs behavior. The H5Mset_ff
+ * routine is identical in functionality, but allows for asynchronous
+ * operation and inclusion in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mset_ff(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, hid_t trans_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "ii*xi*xiii", map_id, key_mem_type_id, key, val_mem_type_id,
+ value, dxpl_id, trans_id, estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ 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")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Set the data through the IOD VOL */
+ if((ret_value = H5VL_iod_map_set(map, key_mem_type_id, key, val_mem_type_id, value,
+ dxpl_id, trans_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set map KV pair")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mset_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_ff
+ *
+ * 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. The
+ * data transfer property list (dxpl_id) may modify the operationÕs
+ * behavior. The H5Mget_ff routine is identical in functionality, but
+ * allows for asynchronous operation and inclusion in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_ff(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, hid_t rcxt_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "ii*xi*xiii", map_id, key_mem_type_id, key, val_mem_type_id,
+ value, dxpl_id, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ 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 plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_map_get(map, key_mem_type_id, key, val_mem_type_id, value,
+ dxpl_id, rcxt_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mget_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_types_ff
+ *
+ * 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. The H5Mget_types_ff routine is identical in
+ * functionality, but allows for asynchronous operation and inclusion
+ * in a transaction. Either (or both) of the datatype ID pointers may
+ * be NULL, if that datatype information is not desired. Any datatype
+ * IDs returned from this routine must be released with H5Tclose.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_types_ff(hid_t map_id, hid_t *key_type_id, hid_t *val_type_id,
+ hid_t rcxt_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "i*i*iii", map_id, key_type_id, val_type_id, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_map_get_types(map, key_type_id, val_type_id, rcxt_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mget_types_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_count_ff
+ *
+ * Purpose:
+ * The H5Mget_count routine retrieves the number of key/value
+ * pairs in a map, given by map_id. The H5Mget_count_ff routine is
+ * identical in functionality, but allows for asynchronous operation
+ * and inclusion in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_count_ff(hid_t map_id, hsize_t *count, hid_t rcxt_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*hii", map_id, count, rcxt_id, estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_map_get_count(map, count, rcxt_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mget_count_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mexists_ff
+ *
+ * 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
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mexists_ff(hid_t map_id, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, hid_t rcxt_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "ii*x*bii", map_id, key_mem_type_id, key, exists, rcxt_id,
+ estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_map_exists(map, key_mem_type_id, key, exists, rcxt_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mexists_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Miterate_ff
+ *
+ * Purpose:
+ * The H5Miterate routine iterates over the key/value pairs
+ * in a map, given by map_id. The user-defined callback routine, given
+ * by callback_func, defined below, will be invoked for each key/value
+ * pair in the map:
+ *
+ * typedef int (*H5M_iterate_func_t)(const void *key, const void *value, void *context);
+ *
+ * Keys and values presented to the
+ * callback routine will be in key_mem_type_id and value_mem_type_id
+ * format, respectively. Additional information may be given to the
+ * callback routine with the context parameter, which is passed
+ * unmodified from the call to H5Miterate to the applicationÕs
+ * callback. The iteration callback routine should obey the same rules
+ * as other HDF5 iteration callbacks: return H5_ITER_ERROR for an error
+ * condition (which will stop iteration), H5_ITER_CONT for success
+ * (with continued iteration) and H5_ITER_STOP for success (but stop
+ * iteration).
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Miterate_ff(hid_t map_id, hid_t key_mem_type_id, hid_t value_mem_type_id,
+ H5M_iterate_func_t callback_func, void *context, hid_t rcxt_id)
+{
+ //void *map = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "iiix*xi", map_id, key_mem_type_id, value_mem_type_id,
+ callback_func, context, rcxt_id);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Miterate */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mdelete_ff
+ *
+ * Purpose:
+ * The H5Mdelete routine removes a key/value pair from a map,
+ * given by map_id. The key value used (pointed to by key) is of type
+ * key_mem_type_id in. The H5Mdelete_ff routine is identical in
+ * functionality, but allows for asynchronous operation and inclusion
+ * in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mdelete_ff(hid_t map_id, hid_t key_mem_type_id, const void *key,
+ hid_t trans_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object created */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "ii*xii", map_id, key_mem_type_id, key, trans_id, estack_id);
+
+ /* check arguments */
+ if(!map_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* delete the key pair through the IOD VOL */
+ if((ret_value = H5VL_iod_map_delete(map, key_mem_type_id, key, trans_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mdelete_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mclose_ff
+ *
+ * Purpose:
+ * The H5Mclose routine terminates access to a map, given by
+ * map_id. The H5Mclose_ff routine is identical in functionality, but
+ * allows for asynchronous operation and inclusion in a transaction.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mclose_ff(hid_t map_id, hid_t estack_id)
+{
+ H5VL_t *vol_plugin = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", map_id, estack_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(map_id, H5I_MAP))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = estack_id;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+
+ /*
+ * Decrement the counter on the group 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_ff */
+
+
+/*-------------------------------------------------------------------------
+ * 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
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5M_close_map(void *map, H5VL_t *vol_plugin)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(vol_plugin->close_estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Close the map through the VOL*/
+ if(H5VL_iod_map_close(map, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close map")
+
+ if(request && *req) {
+ if(H5ES_insert(vol_plugin->close_estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+ vol_plugin->nrefs --;
+ if (0 == vol_plugin->nrefs) {
+ vol_plugin->container_name = (const char *)H5MM_xfree(vol_plugin->container_name);
+ vol_plugin = (H5VL_t *)H5MM_xfree(vol_plugin);
+ }
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M_close_map() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mprefetch
+ *
+ * Purpose: Prefetched a Map from Central Storage to Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Mprefetch(hid_t map_id, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t mapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *map = NULL; /* pointer to map object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == mapl_id)
+ mapl_id = H5P_MAP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(mapl_id, H5P_MAP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not map access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_prefetch(map, rcxt_id, replica_id, mapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't prefetch map")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mprefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mevict
+ *
+ * Purpose: Evicts a Map from Burst Buffer.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_DLL herr_t H5Mevict(hid_t map_id, uint64_t c_version, hid_t mapl_id, hid_t estack_id)
+{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generated request pointer */
+ void *map = NULL; /* pointer to map object */
+ H5VL_t *vol_plugin; /* VOL plugin information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* get the map object */
+ if(NULL == (map = (void *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid map identifier")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == mapl_id)
+ mapl_id = H5P_MAP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(mapl_id, H5P_MAP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not map access property list")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_iod_evict(map, c_version, mapl_id, req)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't evict map")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mevict() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h
new file mode 100644
index 0000000..4a8b8a2
--- /dev/null
+++ b/src/H5Mpublic.h
@@ -0,0 +1,74 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+
+/* Typedef for H5Miterate() callbacks */
+typedef herr_t (*H5M_iterate_func_t)(const void *key, const void *value, void *context);
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+/* API wrappers */
+H5_DLL hid_t H5Mcreate_ff(hid_t loc_id, const char *name, hid_t keytype, hid_t valtype, hid_t lcpl_id,
+ hid_t mcpl_id, hid_t mapl_id, hid_t trans_id, hid_t estack_id);
+H5_DLL hid_t H5Mopen_ff(hid_t loc_id, const char *name, hid_t mapl_id, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Mset_ff(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, hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Mget_ff(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, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Mget_types_ff(hid_t map_id, hid_t *key_type_id, hid_t *val_type_id,
+ hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Mget_count_ff(hid_t map_id, hsize_t *count, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Mexists_ff(hid_t map_id, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5Miterate_ff(hid_t map_id, hid_t key_mem_type_id, hid_t value_mem_type_id,
+ H5M_iterate_func_t callback_func, void *context, hid_t rcxt_id);
+H5_DLL herr_t H5Mdelete_ff(hid_t map_id, hid_t key_mem_type_id, const void *key,
+ hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5Mclose_ff(hid_t map_id, hid_t estack_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5Mpublic_H */
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index a7d386a..d21aff8 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/H5Pdcpl.c b/src/H5Pdcpl.c
index acd48af..550badb 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -43,6 +43,9 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
#include "H5Tprivate.h" /* Datatypes */
+#ifdef H5_HAVE_EFF
+#include "H5VLiod.h" /* IOD plugin */
+#endif
#include "H5Zpkg.h" /* Data filters */
@@ -50,6 +53,14 @@
/* Local Macros */
/****************/
+#ifdef H5_HAVE_EFF
+/* hint that access to dataset will be in an append only fashion */
+#define H5D_CRT_APPEND_ONLY_SIZE sizeof(hbool_t)
+#define H5D_CRT_APPEND_ONLY_DEF FALSE
+#define H5D_CRT_APPEND_ONLY_ENC H5P__encode_hbool_t
+#define H5D_CRT_APPEND_ONLY_DEC H5P__decode_hbool_t
+#endif
+
/* Define default layout information */
#define H5D_DEF_STORAGE_COMPACT_INIT {(hbool_t)FALSE, (size_t)0, NULL}
#define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0}
@@ -170,6 +181,9 @@ H5FL_BLK_EXTERN(type_conv);
/***************************/
/* Property value defaults */
+#ifdef H5_HAVE_EFF
+static const hbool_t H5D_def_append_only_g = H5D_CRT_APPEND_ONLY_DEF;
+#endif
static const H5O_layout_t H5D_def_layout_g = H5D_CRT_LAYOUT_DEF; /* Default storage layout */
static const H5O_fill_t H5D_def_fill_g = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */
static const unsigned H5D_def_alloc_time_state_g = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */
@@ -210,6 +224,14 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass)
FUNC_ENTER_STATIC
+#ifdef H5_HAVE_EFF
+ if(H5P_register_real(pclass, H5D_CRT_APPEND_ONLY_NAME, H5D_CRT_APPEND_ONLY_SIZE,
+ &H5D_def_append_only_g,
+ NULL, NULL, NULL, H5D_CRT_APPEND_ONLY_ENC, H5D_CRT_APPEND_ONLY_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+#endif
+
/* Register the storage layout property */
if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g,
NULL, NULL, NULL, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC,
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index b5d688b..aad2b0d 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -37,15 +37,40 @@
#include "H5ACprivate.h" /* Cache */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5FFprivate.h" /* Fast Forward routines */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
+#include "H5VLiod.h" /* IOD plugin */
/****************/
/* Local Macros */
/****************/
+#ifdef H5_HAVE_EFF
+
+#define H5D_XFER_INJECT_CORRUPTION_SIZE sizeof(hbool_t)
+#define H5D_XFER_INJECT_CORRUPTION_DEF FALSE
+#define H5D_XFER_INJECT_CORRUPTION_ENC H5P__encode_hbool_t
+#define H5D_XFER_INJECT_CORRUPTION_DEC H5P__decode_hbool_t
+
+#define H5D_XFER_CHECKSUM_SIZE sizeof(uint64_t)
+#define H5D_XFER_CHECKSUM_DEF 0
+#define H5D_XFER_CHECKSUM_ENC H5P__encode_uint64_t
+#define H5D_XFER_CHECKSUM_DEC H5P__decode_uint64_t
+
+/* definitions for checksum scope in FF stack */
+#define H5D_XFER_CHECKSUM_SCOPE_SIZE sizeof(uint32_t)
+#define H5D_XFER_CHECKSUM_SCOPE_DEF 7
+#define H5D_XFER_CHECKSUM_SCOPE_ENC H5P__encode_uint32_t
+#define H5D_XFER_CHECKSUM_SCOPE_DEC H5P__decode_uint32_t
+
+#define H5D_XFER_CHECKSUM_PTR_SIZE sizeof(uint64_t *)
+#define H5D_XFER_CHECKSUM_PTR_DEF NULL
+
+#endif /* H5_HAVE_EFF */
+
/* ======== Data transfer properties ======== */
/* Definitions for maximum temp buffer size property */
#define H5D_XFER_MAX_TEMP_BUF_SIZE sizeof(size_t)
@@ -236,6 +261,13 @@ const H5P_libclass_t H5P_CLS_DXFR[1] = {{
/* Local Private Variables */
/***************************/
+#ifdef H5_HAVE_EFF
+static const hbool_t H5D_def_inject_corruption_g = H5D_XFER_INJECT_CORRUPTION_DEF;
+static const uint64_t H5D_def_checksum_g = H5D_XFER_CHECKSUM_DEF;
+static const uint64_t *H5D_def_checksum_ptr_g = H5D_XFER_CHECKSUM_PTR_DEF;
+static const uint32_t H5D_def_checksum_scope_g = H5D_XFER_CHECKSUM_SCOPE_DEF;
+#endif /* H5_HAVE_EFF */
+
/* Property value defaults */
static const size_t H5D_def_max_temp_buf_g = H5D_XFER_MAX_TEMP_BUF_DEF; /* Default value for maximum temp buffer size */
static const void *H5D_def_tconv_buf_g = H5D_XFER_TCONV_BUF_DEF; /* Default value for type conversion buffer */
@@ -284,10 +316,40 @@ static const size_t H5D_def_direct_chunk_datasize_g = H5D_XFER_DIRECT_CHUNK_WRIT
static herr_t
H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
{
+ hid_t trans_id = FAIL;
+ hid_t context_id = FAIL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
+#ifdef H5_HAVE_EFF
+
+ if(H5P_register_real(pclass, H5D_XFER_INJECT_CORRUPTION_NAME, H5D_XFER_INJECT_CORRUPTION_SIZE,
+ &H5D_def_inject_corruption_g,
+ NULL, NULL, NULL, H5D_XFER_INJECT_CORRUPTION_ENC, H5D_XFER_INJECT_CORRUPTION_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ if(H5P_register_real(pclass, H5D_XFER_CHECKSUM_NAME, H5D_XFER_CHECKSUM_SIZE,
+ &H5D_def_checksum_g,
+ NULL, NULL, NULL, H5D_XFER_CHECKSUM_ENC, H5D_XFER_CHECKSUM_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ if(H5P_register_real(pclass, H5VL_CS_BITFLAG_NAME, H5D_XFER_CHECKSUM_SCOPE_SIZE,
+ &H5D_def_checksum_scope_g,
+ NULL, NULL, NULL, H5D_XFER_CHECKSUM_SCOPE_ENC, H5D_XFER_CHECKSUM_SCOPE_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ if(H5P_register_real(pclass, H5D_XFER_CHECKSUM_PTR_NAME, H5D_XFER_CHECKSUM_PTR_SIZE,
+ &H5D_def_checksum_ptr_g,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+#endif /* H5_HAVE_EFF */
+
/* Register the max. temp buffer size property */
if(H5P_register_real(pclass, H5D_XFER_MAX_TEMP_BUF_NAME, H5D_XFER_MAX_TEMP_BUF_SIZE, &H5D_def_max_temp_buf_g,
NULL, NULL, NULL, H5D_XFER_MAX_TEMP_BUF_ENC, H5D_XFER_MAX_TEMP_BUF_DEC,
@@ -462,6 +524,16 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the transaction ID property*/
+ if(H5P_register_real(pclass, H5VL_TRANS_ID, sizeof(hid_t), &trans_id,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register the context ID property*/
+ if(H5P_register_real(pclass, H5VL_CONTEXT_ID, sizeof(hid_t), &context_id,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dxfr_reg_prop() */
diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c
index 0c70c6c..a937feb 100644
--- a/src/H5Pencdec.c
+++ b/src/H5Pencdec.c
@@ -184,6 +184,78 @@ H5P__encode_hsize_t(const void *value, void **_pp, size_t *size)
/*-------------------------------------------------------------------------
+ * Function: H5P__encode_uint32_t
+ *
+ * Purpose: Generic encoding callback routine for 'uint32_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_uint32_t(const void *value, void **_pp, size_t *size)
+{
+ uint8_t **pp = (uint8_t **)_pp;
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the value */
+ UINT32ENCODE(*pp, *(const uint32_t *)value);
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += sizeof(uint32_t);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_uint32_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_uint64_t
+ *
+ * Purpose: Generic encoding callback routine for 'uint64_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_uint64_t(const void *value, void **_pp, size_t *size)
+{
+ uint8_t **pp = (uint8_t **)_pp;
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the value */
+ UINT64ENCODE(*pp, *(const uint64_t *)value);
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += sizeof(uint64_t);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_uint64_t() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__encode_unsigned
*
* Purpose: Generic encoding callback routine for 'unsigned' properties.
@@ -551,6 +623,74 @@ H5P__decode_hsize_t(const void **_pp, void *_value)
/*-------------------------------------------------------------------------
+ * Function: H5P__decode_uint32_t
+ *
+ * Purpose: Generic encoding callback routine for 'uint32_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_uint32_t(const void **_pp, void *_value)
+{
+ uint32_t *value = (uint32_t *)_value; /* Property value to return */
+ const uint8_t **pp = (const uint8_t **)_pp;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ UINT32DECODE(*pp, *value)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_uint32_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_uint64_t
+ *
+ * Purpose: Generic encoding callback routine for 'uint64_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_uint64_t(const void **_pp, void *_value)
+{
+ uint64_t *value = (uint64_t *)_value; /* Property value to return */
+ const uint8_t **pp = (const uint8_t **)_pp;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ UINT64DECODE(*pp, *value)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_uint64_t() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__decode_unsigned
*
* Purpose: Generic decoding callback routine for 'unsigned' properties.
@@ -746,7 +886,7 @@ H5P__decode(const void *buf)
/* Get the type of the property list */
type = (H5P_plist_type_t)*p++;
- if(type <= H5P_TYPE_USER || type > H5P_TYPE_LINK_ACCESS)
+ if(type <= H5P_TYPE_USER || type > H5P_TYPE_TRANSACTION_FINISH)
HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "bad type of encoded information: %u", (unsigned)type)
/* Create new property list of the specified type */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 59c0a2e..bc8d52d 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -36,7 +36,8 @@
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* Files */
+#include "H5Fprivate.h" /* Files */
+#include "H5FFprivate.h" /* FFwd wrappers */
#include "H5FDprivate.h" /* File drivers */
#include "H5VLprivate.h" /* VOL plugins */
#include "H5Iprivate.h" /* IDs */
@@ -58,6 +59,16 @@
/* Local Macros */
/****************/
+#ifdef H5_HAVE_EFF
+
+/* definitions for checksum scope in FF stack */
+#define H5F_ACS_CHECKSUM_SCOPE_SIZE sizeof(uint32_t)
+#define H5F_ACS_CHECKSUM_SCOPE_DEF 7
+#define H5F_ACS_CHECKSUM_SCOPE_ENC H5P__encode_unsigned
+#define H5F_ACS_CHECKSUM_SCOPE_DEC H5P__decode_unsigned
+
+#endif /* H5_HAVE_EFF */
+
/* ========= File Access properties ============ */
/* Definitions for the initial metadata cache resize configuration */
#define H5F_ACS_META_CACHE_INIT_CONFIG_SIZE sizeof(H5AC_cache_config_t)
@@ -258,6 +269,9 @@ static const hbool_t H5F_def_want_posix_fd_g = H5F_ACS_WANT_POSIX_FD_DEF;
static const unsigned H5F_def_efc_size_g = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */
static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */
+#ifdef H5_HAVE_EFF
+static const uint32_t H5F_def_checksum_scope_g = H5F_ACS_CHECKSUM_SCOPE_DEF;
+#endif /* H5_HAVE_EFF */
/*-------------------------------------------------------------------------
@@ -277,6 +291,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
H5VL_class_t *vol_cls = H5F_ACS_VOL_DEF; /* Default VOL plugin */
void *vol_info = H5F_ACS_VOL_INFO_DEF; /* Default VOL plugin information*/
const hid_t def_driver_id = H5F_ACS_FILE_DRV_ID_DEF; /* Default VFL driver ID (initialized from a variable) */
+ hid_t rcxt_id = FAIL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -419,6 +434,19 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
H5F_ACS_FILE_IMAGE_INFO_DEL, H5F_ACS_FILE_IMAGE_INFO_COPY, NULL, H5F_ACS_FILE_IMAGE_INFO_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the read context ID property*/
+ if(H5P_register_real(pclass, H5VL_ACQUIRE_RC_ID, sizeof(hid_t), &rcxt_id,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+#ifdef H5_HAVE_EFF
+ if(H5P_register_real(pclass, H5VL_CS_BITFLAG_NAME, H5F_ACS_CHECKSUM_SCOPE_SIZE,
+ &H5F_def_checksum_scope_g,
+ NULL, NULL, NULL, H5F_ACS_CHECKSUM_SCOPE_ENC, H5F_ACS_CHECKSUM_SCOPE_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+#endif /* H5_HAVE_EFF */
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_facc_reg_prop() */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 8837363..cccc5a4 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -43,6 +43,11 @@
/* Local Macros */
/****************/
+/* Async. I/O properties */
+#define H5P_ASYNC_FLAG_SIZE sizeof(hbool_t)
+#define H5P_ASYNC_REQ_SIZE sizeof(void *)
+#define H5P_ASYNC_REQ_DEF NULL
+
/******************/
/* Local Typedefs */
@@ -89,6 +94,9 @@ static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type)
static herr_t H5P_free_prop(H5P_genprop_t *prop);
static int H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2);
+/* Property class callbacks */
+static herr_t H5P__root_reg_prop(H5P_genclass_t *pclass);
+
/*********************/
/* Package Variables */
@@ -108,13 +116,18 @@ hid_t H5P_CLS_DATASET_XFER_g = FAIL;
hid_t H5P_CLS_FILE_MOUNT_g = FAIL;
hid_t H5P_CLS_GROUP_CREATE_g = FAIL;
hid_t H5P_CLS_GROUP_ACCESS_g = FAIL;
+hid_t H5P_CLS_MAP_CREATE_g = FAIL;
+hid_t H5P_CLS_MAP_ACCESS_g = FAIL;
hid_t H5P_CLS_DATATYPE_CREATE_g = FAIL;
hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL;
hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL;
hid_t H5P_CLS_OBJECT_COPY_g = FAIL;
hid_t H5P_CLS_LINK_CREATE_g = FAIL;
hid_t H5P_CLS_LINK_ACCESS_g = FAIL;
-hid_t H5P_CLS_STRING_CREATE_g = FAIL;
+hid_t H5P_CLS_STRING_CREATE_g = FAIL;
+hid_t H5P_CLS_READ_CONTEXT_ACQUIRE_g = FAIL;
+hid_t H5P_CLS_TRANSACTION_START_g = FAIL;
+hid_t H5P_CLS_TRANSACTION_FINISH_g = FAIL;
/*
* Predefined property lists for each predefined class. These are initialized
@@ -128,12 +141,17 @@ hid_t H5P_LST_DATASET_XFER_g = FAIL;
hid_t H5P_LST_FILE_MOUNT_g = FAIL;
hid_t H5P_LST_GROUP_CREATE_g = FAIL;
hid_t H5P_LST_GROUP_ACCESS_g = FAIL;
+hid_t H5P_LST_MAP_CREATE_g = FAIL;
+hid_t H5P_LST_MAP_ACCESS_g = FAIL;
hid_t H5P_LST_DATATYPE_CREATE_g = FAIL;
hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL;
hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL;
hid_t H5P_LST_OBJECT_COPY_g = FAIL;
hid_t H5P_LST_LINK_CREATE_g = FAIL;
hid_t H5P_LST_LINK_ACCESS_g = FAIL;
+hid_t H5P_LST_READ_CONTEXT_ACQUIRE_g = FAIL;
+hid_t H5P_LST_TRANSACTION_START_g = FAIL;
+hid_t H5P_LST_TRANSACTION_FINISH_g = FAIL;
/* Root property list class library initialization object */
const H5P_libclass_t H5P_CLS_ROOT[1] = {{
@@ -142,7 +160,7 @@ const H5P_libclass_t H5P_CLS_ROOT[1] = {{
NULL, /* Parent class ID */
&H5P_CLS_ROOT_g, /* Pointer to class ID */
NULL, /* Pointer to default property list ID */
- NULL, /* Default property registration routine */
+ H5P__root_reg_prop, /* Default property registration routine */
NULL, /* Class creation callback */
NULL, /* Class creation callback info */
NULL, /* Class copy callback */
@@ -202,12 +220,13 @@ const H5P_libclass_t H5P_CLS_TACC[1] = {{
NULL /* Class close callback info */
}};
-
/* Library property list classes defined in other code modules */
H5_DLLVAR const H5P_libclass_t H5P_CLS_OCRT[1]; /* Object creation */
H5_DLLVAR const H5P_libclass_t H5P_CLS_STRCRT[1]; /* String create */
H5_DLLVAR const H5P_libclass_t H5P_CLS_LACC[1]; /* Link access */
H5_DLLVAR const H5P_libclass_t H5P_CLS_GCRT[1]; /* Group create */
+H5_DLLVAR const H5P_libclass_t H5P_CLS_MCRT[1]; /* Map create */
+H5_DLLVAR const H5P_libclass_t H5P_CLS_MACC[1]; /* Map access */
H5_DLLVAR const H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FCRT[1]; /* File creation */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FACC[1]; /* File access */
@@ -217,7 +236,9 @@ H5_DLLVAR const H5P_libclass_t H5P_CLS_DXFR[1]; /* Data transfer */
H5_DLLVAR const H5P_libclass_t H5P_CLS_FMNT[1]; /* File mount */
H5_DLLVAR const H5P_libclass_t H5P_CLS_ACRT[1]; /* Attribute creation */
H5_DLLVAR const H5P_libclass_t H5P_CLS_LCRT[1]; /* Link creation */
-
+H5_DLLVAR const H5P_libclass_t H5P_CLS_RCACC[1]; /* Read Context acquire */
+H5_DLLVAR const H5P_libclass_t H5P_CLS_TRSCC[1]; /* Transaction start */
+H5_DLLVAR const H5P_libclass_t H5P_CLS_TRFCC[1]; /* Transaction finish */
/*****************************/
/* Library Private Variables */
@@ -244,6 +265,8 @@ static H5P_libclass_t const * const init_class[] = {
H5P_CLS_GCRT, /* Group create */
H5P_CLS_OCPY, /* Object copy */
H5P_CLS_GACC, /* Group access */
+ H5P_CLS_MCRT, /* Map create */
+ H5P_CLS_MACC, /* Map access */
H5P_CLS_FCRT, /* File creation */
H5P_CLS_FACC, /* File access */
H5P_CLS_DCRT, /* Dataset creation */
@@ -253,6 +276,9 @@ static H5P_libclass_t const * const init_class[] = {
H5P_CLS_TCRT, /* Datatype creation */
H5P_CLS_TACC, /* Datatype access */
H5P_CLS_ACRT, /* Attribute creation */
+ H5P_CLS_RCACC, /* Read Context acquire */
+ H5P_CLS_TRSCC, /* Transaction start */
+ H5P_CLS_TRFCC, /* Transaction finish */
H5P_CLS_LCRT /* Link creation */
};
@@ -283,6 +309,10 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{
NULL /* Callback routine for closing auxilary objects of this class */
}};
+/* Property value defaults */
+static const hbool_t H5_def_async_flag_g = H5P_ASYNC_FLAG_DEF; /* Default async flag */
+static const void *H5_def_async_req_g = H5P_ASYNC_REQ_DEF; /* Default async request pointer */
+
/*--------------------------------------------------------------------------
@@ -383,6 +413,42 @@ done:
} /* end H5P_init() */
+/*-------------------------------------------------------------------------
+ * Function: H5P__root_reg_prop
+ *
+ * Purpose: Initialize the root property list class
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__root_reg_prop(H5P_genclass_t *pclass)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Register async. flag property */
+ if(H5P_register_real(pclass, H5P_ASYNC_FLAG_NAME, H5P_ASYNC_FLAG_SIZE, &H5_def_async_flag_g,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+ /* Register async. request property */
+ if(H5P_register_real(pclass, H5P_ASYNC_REQ_NAME, H5P_ASYNC_REQ_SIZE, &H5_def_async_req_g,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__root_reg_prop() */
+
+
/*--------------------------------------------------------------------------
NAME
H5P_init_interface -- Initialize interface-specific information
@@ -526,12 +592,17 @@ H5P_term_interface(void)
H5P_LST_DATASET_XFER_g =
H5P_LST_GROUP_CREATE_g =
H5P_LST_GROUP_ACCESS_g =
+ H5P_LST_MAP_CREATE_g =
+ H5P_LST_MAP_ACCESS_g =
H5P_LST_DATATYPE_CREATE_g =
H5P_LST_DATATYPE_ACCESS_g =
H5P_LST_ATTRIBUTE_CREATE_g =
H5P_LST_OBJECT_COPY_g =
H5P_LST_LINK_CREATE_g =
H5P_LST_LINK_ACCESS_g =
+ H5P_LST_READ_CONTEXT_ACQUIRE_g =
+ H5P_LST_TRANSACTION_START_g =
+ H5P_LST_TRANSACTION_FINISH_g =
H5P_LST_FILE_MOUNT_g = (-1);
} /* end if */
} /* end if */
@@ -551,6 +622,8 @@ H5P_term_interface(void)
H5P_CLS_DATASET_XFER_g =
H5P_CLS_GROUP_CREATE_g =
H5P_CLS_GROUP_ACCESS_g =
+ H5P_CLS_MAP_CREATE_g =
+ H5P_CLS_MAP_ACCESS_g =
H5P_CLS_DATATYPE_CREATE_g =
H5P_CLS_DATATYPE_ACCESS_g =
H5P_CLS_STRING_CREATE_g =
@@ -558,6 +631,9 @@ H5P_term_interface(void)
H5P_CLS_OBJECT_COPY_g =
H5P_CLS_LINK_CREATE_g =
H5P_CLS_LINK_ACCESS_g =
+ H5P_CLS_READ_CONTEXT_ACQUIRE_g =
+ H5P_CLS_TRANSACTION_START_g =
+ H5P_CLS_TRANSACTION_FINISH_g =
H5P_CLS_FILE_MOUNT_g = (-1);
} /* end if */
} /* end if */
@@ -5006,8 +5082,8 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
FUNC_ENTER_PACKAGE
/* Sanity checks */
- HDcompile_assert(H5P_TYPE_LINK_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
- HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_LINK_ACCESS);
+ HDcompile_assert(H5P_TYPE_TRANSACTION_FINISH == (H5P_TYPE_MAX_TYPE - 1));
+ HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_TRANSACTION_FINISH);
/* Check arguments */
if(type == H5P_TYPE_USER)
@@ -5053,6 +5129,14 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
class_id = H5P_CLS_GROUP_ACCESS_g;
break;
+ case H5P_TYPE_MAP_CREATE:
+ class_id = H5P_CLS_MAP_CREATE_g;
+ break;
+
+ case H5P_TYPE_MAP_ACCESS:
+ class_id = H5P_CLS_MAP_ACCESS_g;
+ break;
+
case H5P_TYPE_DATATYPE_CREATE:
class_id = H5P_CLS_DATATYPE_CREATE_g;
break;
@@ -5081,6 +5165,18 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
class_id = H5P_CLS_LINK_ACCESS_g;
break;
+ case H5P_TYPE_READ_CONTEXT_ACQUIRE:
+ class_id = H5P_CLS_READ_CONTEXT_ACQUIRE_g;
+ break;
+
+ case H5P_TYPE_TRANSACTION_START:
+ class_id = H5P_CLS_TRANSACTION_START_g;
+ break;
+
+ case H5P_TYPE_TRANSACTION_FINISH:
+ class_id = H5P_CLS_TRANSACTION_FINISH_g;
+ break;
+
case H5P_TYPE_USER: /* shut compiler warnings up */
case H5P_TYPE_ROOT:
case H5P_TYPE_MAX_TYPE:
diff --git a/src/H5Plapl.c b/src/H5Plapl.c
index 676b574..618cfc9 100644
--- a/src/H5Plapl.c
+++ b/src/H5Plapl.c
@@ -38,13 +38,21 @@
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
-
+#include "H5VLiod.h" /* IOD plugin */
/****************/
/* Local Macros */
/****************/
/* ======== Link access properties ======== */
+#ifdef H5_HAVE_EFF
+/* replica ID to use when accessing an object at IOD */
+#define H5O_ACS_REPLICA_ID_SIZE sizeof(hrpl_t)
+#define H5O_ACS_REPLICA_ID_DEF 0
+#define H5O_ACS_REPLICA_ID_ENC H5P__encode_uint64_t
+#define H5O_ACS_REPLICA_ID_DEC H5P__decode_uint64_t
+#endif
+
/* Definitions for number of soft links to traverse */
#define H5L_ACS_NLINKS_SIZE sizeof(size_t)
#define H5L_ACS_NLINKS_DEF H5L_NUM_LINKS /*max symlinks to follow per lookup */
@@ -151,7 +159,9 @@ static const char *H5L_def_elink_prefix_g = H5L_ACS_ELINK_PREFIX_DEF; /* Default
static const hid_t H5L_def_fapl_id_g = H5L_ACS_ELINK_FAPL_DEF; /* Default fapl for external link access */
static const unsigned H5L_def_elink_flags_g = H5L_ACS_ELINK_FLAGS_DEF; /* Default file access flags for external link traversal */
static const H5L_elink_cb_t H5L_def_elink_cb_g = H5L_ACS_ELINK_CB_DEF; /* Default external link traversal callback */
-
+#ifdef H5_HAVE_EFF
+static const hrpl_t H5O_replica_id_g = H5O_ACS_REPLICA_ID_DEF; /* Default replica ID */
+#endif
/*-------------------------------------------------------------------------
@@ -177,6 +187,14 @@ H5P_lacc_reg_prop(H5P_genclass_t *pclass)
FUNC_ENTER_NOAPI_NOINIT
+#ifdef H5_HAVE_EFF
+ if(H5P_register_real(pclass, H5O_ACS_REPLICA_ID_NAME, H5O_ACS_REPLICA_ID_SIZE,
+ &H5O_replica_id_g,
+ NULL, NULL, NULL, H5O_ACS_REPLICA_ID_ENC, H5O_ACS_REPLICA_ID_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+#endif
+
/* Register property for number of links traversed */
if(H5P_register_real(pclass, H5L_ACS_NLINKS_NAME, H5L_ACS_NLINKS_SIZE, &H5L_def_nlinks_g,
NULL, NULL, NULL, H5L_ACS_NLINKS_ENC, H5L_ACS_NLINKS_DEC,
diff --git a/src/H5Pmapl.c b/src/H5Pmapl.c
new file mode 100644
index 0000000..6884ad8
--- /dev/null
+++ b/src/H5Pmapl.c
@@ -0,0 +1,118 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Pmapl.c
+ * January 27, 2014
+ * Mohamad Chaarawi
+ *
+ * Purpose: Map access property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Map Access properties ============ */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P__macc_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Map creation property list class library initialization object */
+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 ID */
+ &H5P_CLS_MAP_ACCESS_g, /* Pointer to class ID */
+ &H5P_LST_MAP_ACCESS_g, /* Pointer to default property list ID */
+ H5P__macc_reg_prop, /* 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__macc_reg_prop
+ *
+ * Purpose: Initialize the map access property list class
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2014
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__macc_reg_prop(H5P_genclass_t *pclass)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__macc_reg_prop() */
diff --git a/src/H5Pmcpl.c b/src/H5Pmcpl.c
new file mode 100644
index 0000000..20ae66d
--- /dev/null
+++ b/src/H5Pmcpl.c
@@ -0,0 +1,118 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Pmcpl.c
+ * January 27, 2014
+ * Mohamad Chaarawi
+ *
+ * Purpose: Map creation property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Map Creation properties ============ */
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P__mcrt_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Map creation property list class library initialization object */
+const H5P_libclass_t H5P_CLS_MCRT[1] = {{
+ "map create", /* Class name for debugging */
+ H5P_TYPE_MAP_CREATE, /* Class type */
+ &H5P_CLS_OBJECT_CREATE_g, /* Parent class ID */
+ &H5P_CLS_MAP_CREATE_g, /* Pointer to class ID */
+ &H5P_LST_MAP_CREATE_g, /* Pointer to default property list ID */
+ H5P__mcrt_reg_prop, /* 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__mcrt_reg_prop
+ *
+ * Purpose: Initialize the map creation property list class
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2014
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__mcrt_reg_prop(H5P_genclass_t *pclass)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__mcrt_reg_prop() */
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index df4ebb6..8d1d061 100644
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -49,6 +49,13 @@
/****************/
/* ========= Object Creation properties ============ */
+#ifdef H5_HAVE_EFF
+/* hint for IOD to enable checksums on an object */
+#define H5O_CRT_ENABLE_CHECKSUM_SIZE sizeof(hbool_t)
+#define H5O_CRT_ENABLE_CHECKSUM_DEF TRUE
+#define H5O_CRT_ENABLE_CHECKSUM_ENC H5P__encode_hbool_t
+#define H5O_CRT_ENABLE_CHECKSUM_DEC H5P__decode_hbool_t
+#endif
/* Definitions for the max. # of attributes to store compactly */
#define H5O_CRT_ATTR_MAX_COMPACT_SIZE sizeof(unsigned)
#define H5O_CRT_ATTR_MAX_COMPACT_ENC H5P__encode_unsigned
@@ -132,7 +139,9 @@ static const unsigned H5O_def_attr_max_compact_g = H5O_CRT_ATTR_MAX_COMPACT_DEF;
static const unsigned H5O_def_attr_min_dense_g = H5O_CRT_ATTR_MIN_DENSE_DEF; /* Default min. dense attribute storage settings */
static const uint8_t H5O_def_ohdr_flags_g = H5O_CRT_OHDR_FLAGS_DEF; /* Default object header flag settings */
static const H5O_pline_t H5O_def_pline_g = H5O_CRT_PIPELINE_DEF; /* Default I/O pipeline setting */
-
+#ifdef H5_HAVE_EFF
+static const hbool_t H5O_def_enable_checksum_g = H5O_CRT_ENABLE_CHECKSUM_DEF;
+#endif
/*-------------------------------------------------------------------------
@@ -154,6 +163,14 @@ H5P__ocrt_reg_prop(H5P_genclass_t *pclass)
FUNC_ENTER_STATIC
+#ifdef H5_HAVE_EFF
+ if(H5P_register_real(pclass, H5O_CRT_ENABLE_CHECKSUM_NAME, H5O_CRT_ENABLE_CHECKSUM_SIZE,
+ &H5O_def_enable_checksum_g,
+ NULL, NULL, NULL, H5O_CRT_ENABLE_CHECKSUM_ENC, H5O_CRT_ENABLE_CHECKSUM_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+#endif
+
/* Register max. compact attribute storage property */
if(H5P_register_real(pclass, H5O_CRT_ATTR_MAX_COMPACT_NAME, H5O_CRT_ATTR_MAX_COMPACT_SIZE, &H5O_def_attr_max_compact_g,
NULL, NULL, NULL, H5O_CRT_ATTR_MAX_COMPACT_ENC, H5O_CRT_ATTR_MAX_COMPACT_DEC,
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index 9d48c60..4bf3e66 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -211,12 +211,16 @@ H5_DLL herr_t H5P__encode_hsize_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__encode_size_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__encode_unsigned(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__encode_uint8_t(const void *value, void **_pp, size_t *size);
+H5_DLL herr_t H5P__encode_uint32_t(const void *value, void **_pp, size_t *size);
+H5_DLL herr_t H5P__encode_uint64_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__encode_hbool_t(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__encode_double(const void *value, void **_pp, size_t *size);
H5_DLL herr_t H5P__decode_hsize_t(const void **_pp, void *value);
H5_DLL herr_t H5P__decode_size_t(const void **_pp, void *value);
H5_DLL herr_t H5P__decode_unsigned(const void **_pp, void *value);
H5_DLL herr_t H5P__decode_uint8_t(const void **_pp, void *value);
+H5_DLL herr_t H5P__decode_uint64_t(const void **_pp, void *value);
+H5_DLL herr_t H5P__decode_uint32_t(const void **_pp, void *value);
H5_DLL herr_t H5P__decode_hbool_t(const void **_pp, void *value);
H5_DLL herr_t H5P__decode_double(const void **_pp, void *value);
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 0c3b5aa..2d78d5c 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -35,6 +35,11 @@
/* ======== String creation property names ======== */
#define H5P_STRCRT_CHAR_ENCODING_NAME "character_encoding" /* Character set encoding for string */
+/* ======== Root property names ======== */
+#define H5P_ASYNC_FLAG_NAME "async flag" /* Async flag */
+#define H5P_ASYNC_FLAG_DEF FALSE
+#define H5P_ASYNC_REQ_NAME "async request" /* Async request */
+
/****************************/
/* Library Private Typedefs */
@@ -63,6 +68,11 @@ typedef enum H5P_plist_type_t {
H5P_TYPE_OBJECT_COPY = 15,
H5P_TYPE_LINK_CREATE = 16,
H5P_TYPE_LINK_ACCESS = 17,
+ H5P_TYPE_MAP_CREATE = 18,
+ H5P_TYPE_MAP_ACCESS = 19,
+ H5P_TYPE_READ_CONTEXT_ACQUIRE = 20,
+ H5P_TYPE_TRANSACTION_START = 21,
+ H5P_TYPE_TRANSACTION_FINISH = 22,
H5P_TYPE_MAX_TYPE
} H5P_plist_type_t;
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 882b195..6ff9fca 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -62,6 +62,8 @@
#define H5P_FILE_MOUNT (H5OPEN H5P_CLS_FILE_MOUNT_g)
#define H5P_GROUP_CREATE (H5OPEN H5P_CLS_GROUP_CREATE_g)
#define H5P_GROUP_ACCESS (H5OPEN H5P_CLS_GROUP_ACCESS_g)
+#define H5P_MAP_CREATE (H5OPEN H5P_CLS_MAP_CREATE_g)
+#define H5P_MAP_ACCESS (H5OPEN H5P_CLS_MAP_ACCESS_g)
#define H5P_DATATYPE_CREATE (H5OPEN H5P_CLS_DATATYPE_CREATE_g)
#define H5P_DATATYPE_ACCESS (H5OPEN H5P_CLS_DATATYPE_ACCESS_g)
#define H5P_STRING_CREATE (H5OPEN H5P_CLS_STRING_CREATE_g)
@@ -69,6 +71,9 @@
#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_g)
#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_g)
#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_g)
+#define H5P_RC_ACQUIRE (H5OPEN H5P_CLS_READ_CONTEXT_ACQUIRE_g)
+#define H5P_TR_START (H5OPEN H5P_CLS_TRANSACTION_START_g)
+#define H5P_TR_FINISH (H5OPEN H5P_CLS_TRANSACTION_FINISH_g)
/*
* The library's default property lists
@@ -81,12 +86,17 @@
#define H5P_FILE_MOUNT_DEFAULT (H5OPEN H5P_LST_FILE_MOUNT_g)
#define H5P_GROUP_CREATE_DEFAULT (H5OPEN H5P_LST_GROUP_CREATE_g)
#define H5P_GROUP_ACCESS_DEFAULT (H5OPEN H5P_LST_GROUP_ACCESS_g)
+#define H5P_MAP_CREATE_DEFAULT (H5OPEN H5P_LST_MAP_CREATE_g)
+#define H5P_MAP_ACCESS_DEFAULT (H5OPEN H5P_LST_MAP_ACCESS_g)
#define H5P_DATATYPE_CREATE_DEFAULT (H5OPEN H5P_LST_DATATYPE_CREATE_g)
#define H5P_DATATYPE_ACCESS_DEFAULT (H5OPEN H5P_LST_DATATYPE_ACCESS_g)
#define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_g)
#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_g)
#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_g)
#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_g)
+#define H5P_RC_ACQUIRE_DEFAULT (H5OPEN H5P_LST_READ_CONTEXT_ACQUIRE_g)
+#define H5P_TR_START_DEFAULT (H5OPEN H5P_LST_TRANSACTION_START_g)
+#define H5P_TR_FINISH_DEFAULT (H5OPEN H5P_LST_TRANSACTION_FINISH_g)
/* Common creation order flags (for links in groups and attributes on objects) */
#define H5P_CRT_ORDER_TRACKED 0x0001
@@ -183,6 +193,8 @@ H5_DLLVAR hid_t H5P_CLS_DATASET_XFER_g;
H5_DLLVAR hid_t H5P_CLS_FILE_MOUNT_g;
H5_DLLVAR hid_t H5P_CLS_GROUP_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_GROUP_ACCESS_g;
+H5_DLLVAR hid_t H5P_CLS_MAP_CREATE_g;
+H5_DLLVAR hid_t H5P_CLS_MAP_ACCESS_g;
H5_DLLVAR hid_t H5P_CLS_DATATYPE_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_DATATYPE_ACCESS_g;
H5_DLLVAR hid_t H5P_CLS_STRING_CREATE_g;
@@ -190,6 +202,9 @@ H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_g;
H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_g;
+H5_DLLVAR hid_t H5P_CLS_READ_CONTEXT_ACQUIRE_g;
+H5_DLLVAR hid_t H5P_CLS_TRANSACTION_START_g;
+H5_DLLVAR hid_t H5P_CLS_TRANSACTION_FINISH_g;
/* Default roperty list IDs */
/* (Internal to library, do not use! Use macros above) */
@@ -201,12 +216,17 @@ H5_DLLVAR hid_t H5P_LST_DATASET_XFER_g;
H5_DLLVAR hid_t H5P_LST_FILE_MOUNT_g;
H5_DLLVAR hid_t H5P_LST_GROUP_CREATE_g;
H5_DLLVAR hid_t H5P_LST_GROUP_ACCESS_g;
+H5_DLLVAR hid_t H5P_LST_MAP_CREATE_g;
+H5_DLLVAR hid_t H5P_LST_MAP_ACCESS_g;
H5_DLLVAR hid_t H5P_LST_DATATYPE_CREATE_g;
H5_DLLVAR hid_t H5P_LST_DATATYPE_ACCESS_g;
H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_CREATE_g;
H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_g;
H5_DLLVAR hid_t H5P_LST_LINK_CREATE_g;
H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_g;
+H5_DLLVAR hid_t H5P_LST_READ_CONTEXT_ACQUIRE_g;
+H5_DLLVAR hid_t H5P_LST_TRANSACTION_START_g;
+H5_DLLVAR hid_t H5P_LST_TRANSACTION_FINISH_g;
/*********************/
/* Public Prototypes */
diff --git a/src/H5Prcapl.c b/src/H5Prcapl.c
new file mode 100644
index 0000000..1e24e09
--- /dev/null
+++ b/src/H5Prcapl.c
@@ -0,0 +1,131 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Prcapl.c
+ * August 2013
+ * Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ *
+ * Purpose: Read Context Acquire property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+#include "H5RCprivate.h" /* Read Context */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Read Context properties ============ */
+/* Definitions for Container Version being Acquired */
+#define H5RC_ACQUIRE_CV_REQUEST_SIZE sizeof(H5RC_request_t)
+#define H5RC_ACQUIRE_CV_REQUEST_DEF H5RC_EXACT
+#define H5RC_ACQUIRE_CV_REQUEST_ENC H5P__encode_unsigned
+#define H5RC_ACQUIRE_CV_REQUEST_DEC H5P__decode_unsigned
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P__rcacc_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Read Context acquire property list class library initialization object */
+const H5P_libclass_t H5P_CLS_RCACC[1] = {{
+ "read context acquire", /* Class name for debugging */
+ H5P_TYPE_READ_CONTEXT_ACQUIRE, /* Class type */
+ &H5P_CLS_ROOT_g, /* Parent class ID */
+ &H5P_CLS_READ_CONTEXT_ACQUIRE_g, /* Pointer to class ID */
+ &H5P_LST_READ_CONTEXT_ACQUIRE_g, /* Pointer to default property list ID */
+ H5P__rcacc_reg_prop, /* 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__rcacc_reg_prop
+ *
+ * Purpose: Register the read context acquire property list class's
+ * properties
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__rcacc_reg_prop(H5P_genclass_t *pclass)
+{
+ H5RC_request_t acquire_req = H5RC_ACQUIRE_CV_REQUEST_DEF;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Register the size of raw data chunk cache (elements) */
+ if(H5P_register_real(pclass, H5RC_ACQUIRE_CV_REQUEST_NAME, H5RC_ACQUIRE_CV_REQUEST_SIZE, &acquire_req,
+ NULL, NULL, NULL, H5RC_ACQUIRE_CV_REQUEST_ENC, H5RC_ACQUIRE_CV_REQUEST_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__rcacc_reg_prop() */
diff --git a/src/H5Ptrfpl.c b/src/H5Ptrfpl.c
new file mode 100644
index 0000000..3029ff1
--- /dev/null
+++ b/src/H5Ptrfpl.c
@@ -0,0 +1,132 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Ptrspl.c
+ * August 2013
+ * Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ *
+ * Purpose: Transaction Finish property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+#include "H5TRprivate.h" /* Transactions */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Read Context properties ============ */
+/* Definitions for Transaction being finished */
+#define H5TR_FINISH_ACQUIRE_SIZE sizeof(hbool_t)
+#define H5TR_FINISH_ACQUIRE_DEF FALSE
+#define H5TR_FINISH_ACQUIRE_ENC H5P__encode_hbool_t
+#define H5TR_FINISH_ACQUIRE_DEC H5P__decode_hbool_t
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P__trfcc_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Transaction finish property list class library initialization object */
+const H5P_libclass_t H5P_CLS_TRFCC[1] = {{
+ "transaction finish", /* Class name for debugging */
+ H5P_TYPE_TRANSACTION_FINISH, /* Class type */
+ &H5P_CLS_ROOT_g, /* Parent class ID */
+ &H5P_CLS_TRANSACTION_FINISH_g, /* Pointer to class ID */
+ &H5P_LST_TRANSACTION_FINISH_g, /* Pointer to default property list ID */
+ H5P__trfcc_reg_prop, /* 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__trfcc_reg_prop
+ *
+ * Purpose: Register the transaction finish property list class's
+ * properties
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__trfcc_reg_prop(H5P_genclass_t *pclass)
+{
+ hbool_t acquire = H5TR_FINISH_ACQUIRE_DEF;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Register the size of raw data chunk cache (elements) */
+ if(H5P_register_real(pclass, H5TR_FINISH_ACQUIRE_NAME, H5TR_FINISH_ACQUIRE_SIZE, &acquire,
+ NULL, NULL, NULL, H5TR_FINISH_ACQUIRE_ENC, H5TR_FINISH_ACQUIRE_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__trfcc_reg_prop() */
+
diff --git a/src/H5Ptrspl.c b/src/H5Ptrspl.c
new file mode 100644
index 0000000..c75c761
--- /dev/null
+++ b/src/H5Ptrspl.c
@@ -0,0 +1,131 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Ptrspl.c
+ * August 2013
+ * Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ *
+ * Purpose: Transaction Start property list class routines
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Ppkg.h" /* Property lists */
+#include "H5TRprivate.h" /* Transactions */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* ========= Read Context properties ============ */
+/* Definitions for Transaction being started */
+#define H5TR_START_NUM_PEERS_SIZE sizeof(unsigned)
+#define H5TR_START_NUM_PEERS_DEF 0
+#define H5TR_START_NUM_PEERS_ENC H5P__encode_unsigned
+#define H5TR_START_NUM_PEERS_DEC H5P__decode_unsigned
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* Property class callbacks */
+static herr_t H5P__trscc_reg_prop(H5P_genclass_t *pclass);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Transaction start property list class library initialization object */
+const H5P_libclass_t H5P_CLS_TRSCC[1] = {{
+ "transaction start", /* Class name for debugging */
+ H5P_TYPE_TRANSACTION_START, /* Class type */
+ &H5P_CLS_ROOT_g, /* Parent class ID */
+ &H5P_CLS_TRANSACTION_START_g, /* Pointer to class ID */
+ &H5P_LST_TRANSACTION_START_g, /* Pointer to default property list ID */
+ H5P__trscc_reg_prop, /* 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 */
+}};
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__trscc_reg_prop
+ *
+ * Purpose: Register the transaction start property list class's
+ * properties
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__trscc_reg_prop(H5P_genclass_t *pclass)
+{
+ unsigned num_peers = H5TR_START_NUM_PEERS_DEF;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Register the size of raw data chunk cache (elements) */
+ if(H5P_register_real(pclass, H5TR_START_NUM_PEERS_NAME, H5TR_START_NUM_PEERS_SIZE, &num_peers,
+ NULL, NULL, NULL, H5TR_START_NUM_PEERS_ENC, H5TR_START_NUM_PEERS_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__trscc_reg_prop() */
diff --git a/src/H5Q.c b/src/H5Q.c
new file mode 100644
index 0000000..1884dd4
--- /dev/null
+++ b/src/H5Q.c
@@ -0,0 +1,1220 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: Query routines.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5Q_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Qprivate.h" /* Query */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h"
+
+/****************/
+/* Local Macros */
+/****************/
+#define H5Q_TYPE_SEQ \
+ ((H5T_NATIVE_CHAR)(char))\
+ ((H5T_NATIVE_SHORT)(short)) \
+ ((H5T_NATIVE_INT)(int)) \
+ ((H5T_NATIVE_LONG)(long)) \
+ ((H5T_NATIVE_LLONG)(long long)) \
+ ((H5T_NATIVE_FLOAT)(float)) \
+ ((H5T_NATIVE_DOUBLE)(double))
+
+#define H5Q_APPLY_MATCH_OP(result, op, x, y) \
+ switch (op) { \
+ case H5Q_MATCH_EQUAL: \
+ result = (x == y); \
+ break; \
+ case H5Q_MATCH_NOT_EQUAL: \
+ result = (x != y); \
+ break; \
+ case H5Q_MATCH_LESS_THAN: \
+ result = (x < y); \
+ break; \
+ case H5Q_MATCH_GREATER_THAN: \
+ result = (x > y); \
+ break; \
+ default: \
+ break; \
+ }
+
+#define H5Q_CMP_DATA_ELEM(result, op, type, x, y) \
+{ \
+ type x_value; \
+ type y_value; \
+ x_value = *((type *) x); \
+ y_value = *((type *) y); \
+ \
+ H5Q_APPLY_MATCH_OP(result, op, x_value, y_value) \
+}
+
+#define H5Q_CMP_TYPE(type1, type2, native_type) \
+ (0 == H5T_cmp(type1, native_type, FALSE)) || \
+ (0 == H5T_cmp(type2, native_type, FALSE))
+
+/******************/
+/* Local Typedefs */
+/******************/
+typedef enum H5Q_match_type_t { /* The different kinds of native types we can match */
+ H5Q_NATIVE_INT_MATCH_CHAR,
+ H5Q_NATIVE_INT_MATCH_SHORT,
+ H5Q_NATIVE_INT_MATCH_INT,
+ H5Q_NATIVE_INT_MATCH_LONG,
+ H5Q_NATIVE_INT_MATCH_LLONG,
+ H5Q_NATIVE_FLOAT_MATCH_FLOAT,
+ H5Q_NATIVE_FLOAT_MATCH_DOUBLE
+} H5Q_match_type_t;
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5Q_apply_combine(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_select(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_data_elem(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_attr_name(H5Q_t *query, hbool_t *result,
+ const char *name);
+static herr_t H5Q_apply_link_name(H5Q_t *query, hbool_t *result,
+ const char *name);
+
+static H5_inline void
+H5Q_encode_memcpy(unsigned char **buf_ptr, size_t *nalloc, const void *data,
+ size_t data_size)
+{
+ if (*buf_ptr != NULL) {
+ HDmemcpy(*buf_ptr, data, data_size);
+ *buf_ptr += data_size;
+ }
+ *nalloc += data_size;
+}
+
+static H5_inline void
+H5Q_decode_memcpy(void *data, size_t data_size, const unsigned char **buf_ptr)
+{
+ if (*buf_ptr != NULL) {
+ HDmemcpy(data, *buf_ptr, data_size);
+ *buf_ptr += data_size;
+ }
+}
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5Q_t struct */
+H5FL_DEFINE(H5Q_t);
+
+/* Query ID class */
+static const H5I_class_t H5I_QUERY_CLS[1] = {{
+ H5I_QUERY, /* Class ID for the type */
+ 0, /* Class behavior flags */
+ 0, /* Number of reserved IDs for this type */
+ (H5I_free_t)H5Q_close, /* Free function for object's of this type */
+ NULL /* Free function for auxilary objects of this type */
+}};
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_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 H5Q_init() */
+
+/*--------------------------------------------------------------------------
+NAME
+ H5Q_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5Q_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5Q_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Initialize the atom group for the QUERY IDs */
+ if (H5I_register_type(H5I_QUERY_CLS) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_init_interface() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Q_term_interface
+ PURPOSE
+ Terminate various H5Q objects
+ USAGE
+ void H5Q_term_interface()
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5Q_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if (H5_interface_initialize_g) {
+ if ((n = H5I_nmembers(H5I_QUERY))) {
+ H5I_clear_type(H5I_QUERY, FALSE, FALSE);
+ } /* end if */
+ else {
+ /* Free data types */
+ H5I_dec_type_ref(H5I_QUERY);
+
+ /* Shut down interface */
+ H5_interface_initialize_g = 0;
+ n = 1; /* H5I */
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5Q_term_interface() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qcreate
+ *
+ * Purpose: Create a new query object of query_type type, with match_op
+ * determining the query's match condition and additional parameters
+ * determined by the type of the query.
+ *
+ * Return: Success: The ID for a new query.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qcreate(H5Q_type_t query_type, H5Q_match_op_t match_op, ...)
+{
+ H5Q_t *query = NULL;
+ va_list ap;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("i", "QtQm", query_type, match_op);
+
+ va_start(ap, match_op);
+
+ switch (query_type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ H5T_t *datatype = NULL;
+ hid_t datatype_id;
+ const void *value;
+
+ /* Get arguments */
+ datatype_id = va_arg(ap, hid_t);
+ value = va_arg(ap, const void *);
+
+ /* Get type */
+ if (NULL == (datatype = (H5T_t *) H5I_object_verify(datatype_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, datatype, value)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ const char *attr_name;
+
+ /* Get arguments */
+ attr_name = va_arg(ap, const char *);
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, attr_name)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ const char *link_name;
+
+ /* Get arguments */
+ link_name = va_arg(ap, const char *);
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, link_name)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ default:
+ {
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ }
+ break;
+ }
+
+ va_end(ap);
+
+ /* Register the new query object to get an ID for it */
+ if ((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "can't register query handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qcreate() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_create
+ *
+ * Purpose: Private function for H5Qcreate
+ *
+ * Return: Success: Pointer to the new query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_create(H5Q_type_t query_type, H5Q_match_op_t match_op, ...)
+{
+ H5Q_t *query = NULL;
+ va_list ap;
+ H5Q_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ va_start(ap, match_op);
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ query->is_combined = FALSE;
+ query->ref_count = 1;
+ query->query.select.type = query_type;
+ query->query.select.match_op = match_op;
+ switch (query_type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ H5T_t *datatype = NULL;
+ H5T_t *native_datatype = NULL;
+ size_t datatype_size;
+ const void *value;
+ void *value_buf = NULL;
+
+ datatype = va_arg(ap, H5T_t*);
+ value = va_arg(ap, const void *);
+
+ /* Only use native type */
+ if (NULL == (native_datatype = H5T_get_native_type(datatype, H5T_DIR_DEFAULT, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve native type")
+ query->query.select.elem.data_elem.type = native_datatype;
+ if (0 == (datatype_size = H5T_get_size(native_datatype)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size")
+ query->query.select.elem.data_elem.type_size = datatype_size;
+ if (NULL == (value_buf = H5MM_malloc(datatype_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ HDmemcpy(value_buf, value, datatype_size);
+ query->query.select.elem.data_elem.value = value_buf;
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ const char *attr_name;
+
+ attr_name = va_arg(ap, const char *);
+ query->query.select.elem.attr_name.name = H5MM_strdup(attr_name);
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ const char *link_name;
+
+ link_name = va_arg(ap, const char *);
+ query->query.select.elem.link_name.name = H5MM_strdup(link_name);
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized query type")
+ break;
+ } /* end switch */
+
+ va_end(ap);
+
+ /* set return value */
+ ret_value = query;
+
+done:
+ if (!ret_value && query)
+ query = H5FL_FREE(H5Q_t, query);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_create() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qclose
+ *
+ * Purpose: Close a query object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qclose(hid_t query_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", query_id);
+
+ /* Check args */
+ if (NULL == H5I_object_verify(query_id, H5I_QUERY))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+
+ if (H5I_dec_app_ref(query_id) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTDEC, FAIL, "unable to decrement ref count on query");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qclose() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_close
+ *
+ * Purpose: Private function for H5Qclose.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_close(H5Q_t *query)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(query);
+
+ query->ref_count--;
+ if (query->ref_count) HGOTO_DONE(SUCCEED)
+
+ if (query->is_combined) {
+ if (FAIL == H5Q_close(query->query.combine.l_query))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free query")
+ query->query.combine.l_query = NULL;
+ if (FAIL == H5Q_close(query->query.combine.r_query))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free query")
+ query->query.combine.r_query = NULL;
+ } else {
+ switch (query->query.select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ if (FAIL == H5T_close(query->query.select.elem.data_elem.type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free datatype");
+ query->query.select.elem.data_elem.type = NULL;
+ H5MM_free(query->query.select.elem.data_elem.value);
+ query->query.select.elem.data_elem.value = NULL;
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ H5MM_free(query->query.select.elem.attr_name.name);
+ query->query.select.elem.attr_name.name = NULL;
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ H5MM_free(query->query.select.elem.link_name.name);
+ query->query.select.elem.link_name.name = NULL;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ /* Free the query struct */
+ query = H5FL_FREE(H5Q_t, query);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qcombine
+ *
+ * Purpose: Combine query objects to create a new query object.
+ *
+ * Return: Success: The ID for a new combined query.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qcombine(hid_t query_id1, H5Q_combine_op_t combine_op, hid_t query_id2)
+{
+ H5Q_t *query = NULL, *query1 = NULL, *query2 = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("i", "iQci", query_id1, combine_op, query_id2);
+
+ /* Check args and get the query objects */
+ if(NULL == (query1 = (H5Q_t *) H5I_object_verify(query_id1, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(NULL == (query2 = (H5Q_t *) H5I_object_verify(query_id2, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+
+ /* Combine query objects */
+ if (NULL == (query = H5Q_combine(query1, combine_op, query2)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to combine query objects")
+
+ /* Register the new query object to get an ID for it */
+ if ((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "can't register query handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qcombine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_combine
+ *
+ * Purpose: Private function for H5Qcombine.
+ *
+ * Return: Success: Pointer to the new query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_combine(H5Q_t *query1, H5Q_combine_op_t combine_op, H5Q_t *query2)
+{
+ H5Q_t *query = NULL;
+ H5Q_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ switch (combine_op) {
+ case H5Q_COMBINE_AND:
+ case H5Q_COMBINE_OR:
+ query->query.combine.op = combine_op;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized combine op")
+ break;
+ }
+ query->is_combined = TRUE;
+ query->ref_count = 1;
+ query->query.combine.l_query = query1;
+ query1->ref_count++;
+ query->query.combine.r_query = query2;
+ query2->ref_count++;
+
+ /* set return value */
+ ret_value = query;
+
+done:
+ if (!ret_value && query)
+ query = H5FL_FREE(H5Q_t, query);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_combine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qapply
+ *
+ * Purpose: Apply a query to an element elem of type type_id.
+ * TODO modify prototype for attr/link name support
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qapply(hid_t query_id, hbool_t *result, hid_t type_id, const void *elem)
+{
+ H5Q_t *query = NULL;
+ H5T_t *type = NULL, *native_type = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "i*bi*x", query_id, result, type_id, elem);
+
+ /* Check args and get the query objects */
+ if (!result)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for result")
+ if (NULL == (query = (H5Q_t *) H5I_object_verify(query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(NULL == (type = (H5T_t *) H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+
+ /* Only use native type */
+ if (NULL == (native_type = H5T_get_native_type(type, H5T_DIR_DEFAULT, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type")
+
+ /* Apply query */
+ if (FAIL == (ret_value = H5Q_apply(query, result, native_type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+
+done:
+ if (native_type)
+ H5T_close(native_type);
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qapply() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply
+ *
+ * Purpose: Private function for H5Qapply.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_apply(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(result);
+
+ if (query->is_combined) {
+ if (FAIL == (ret_value = H5Q_apply_combine(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ } else {
+ if (FAIL == (ret_value = H5Q_apply_select(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_combine
+ *
+ * Purpose: Private function for H5Qapply (combine query).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_combine(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t result1, result2;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->is_combined == TRUE);
+
+ if (FAIL == H5Q_apply(query->query.combine.l_query, &result1, type, elem))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ if (FAIL == H5Q_apply(query->query.combine.r_query, &result2, type, elem))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+
+ switch (query->query.combine.op) {
+ case H5Q_COMBINE_AND:
+ *result = result1 && result2;
+ break;
+ case H5Q_COMBINE_OR:
+ *result = result1 || result2;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized combine op")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_combine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_select
+ *
+ * Purpose: Private function for H5Qapply (select query).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_select(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->is_combined == FALSE);
+
+ switch (query->query.select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ if (FAIL == (ret_value = H5Q_apply_data_elem(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply data element query")
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ /* TODO pass non NULL string */
+ if (FAIL == (ret_value = H5Q_apply_attr_name(query, result, NULL)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply attribute name query")
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ /* TODO pass non NULL string */
+ if (FAIL == (ret_value = H5Q_apply_link_name(query, result, NULL)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply link name query")
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_select() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_promote_type
+ *
+ * Purpose: Private function for H5Qapply (promote data element type
+ * so that data element and query element can be compared).
+ *
+ * Return: Success: Pointer to promoted native type
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5Q_promote_type(H5T_t *type1, H5T_t *type2, H5Q_match_type_t *match_type)
+{
+ H5T_t *ret_value; /* Return value */
+ H5T_class_t type1_class, type2_class, promoted_type_class;
+ H5T_t *promoted_type;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get class of types */
+ if (H5T_NO_CLASS == (type1_class = H5T_get_class(type1, FALSE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+ if (H5T_NO_CLASS == (type2_class = H5T_get_class(type2, FALSE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+
+ if ((type1_class == H5T_FLOAT) || (type2_class == H5T_FLOAT)) {
+ promoted_type_class = H5T_FLOAT;
+ } else {
+ promoted_type_class = H5T_INTEGER;
+ }
+
+ switch (promoted_type_class) {
+ case H5T_INTEGER:
+ if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_LLONG_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_LLONG;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_LLONG_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_LONG_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_LONG;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_LONG_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_INT_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_INT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_INT_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_SHORT_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_SHORT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_SHORT_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_CHAR;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g);
+ } else {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid type")
+ }
+ break;
+ case H5T_FLOAT:
+ if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g))) {
+ *match_type = H5Q_NATIVE_FLOAT_MATCH_DOUBLE;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g))) {
+ *match_type = H5Q_NATIVE_FLOAT_MATCH_FLOAT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g);
+ } else {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid type")
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+ break;
+ }
+
+ ret_value = promoted_type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_promote_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_data_elem
+ *
+ * Purpose: Private function for H5Qapply (data element).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_data_elem(H5Q_t *query, hbool_t *result, H5T_t *type, const void *value)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ void *value_buf = NULL, *query_value_buf = NULL;
+ H5T_t *query_type, *promoted_type;
+ H5Q_match_type_t match_type;
+ size_t type_size, query_type_size, promoted_type_size;
+ hid_t type_id, query_type_id, promoted_type_id;
+ H5T_path_t *tpath;
+ H5Q_match_op_t query_op;
+ hbool_t query_result = FALSE;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->query.select.type == H5Q_TYPE_DATA_ELEM);
+
+ /* Keep a copy of elem to work on */
+ if (0 == (type_size = H5T_get_size(type)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size")
+
+ /* Keep a copy of the query value */
+ query_type = query->query.select.elem.data_elem.type;
+ query_type_size = query->query.select.elem.data_elem.type_size;
+ query_op = query->query.select.match_op;
+
+ /* Promote type to compare elements with query */
+ promoted_type = H5Q_promote_type(type, query_type, &match_type);
+ if (0 == (promoted_type_size = H5T_get_size(promoted_type)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size")
+
+ /* Resize value and query value buf for convert
+ * (promoted_type_size is always bigger) */
+ if (NULL == (value_buf = H5MM_malloc(promoted_type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer")
+ HDmemcpy(value_buf, value, type_size);
+
+ if (NULL == (query_value_buf = H5MM_malloc(promoted_type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer")
+ HDmemcpy(query_value_buf, query->query.select.elem.data_elem.value, query_type_size);
+
+ /* Create temporary IDs for H5T_convert */
+ type_id = H5I_register(H5I_DATATYPE, type, FALSE);
+ query_type_id = H5I_register(H5I_DATATYPE, query_type, FALSE);
+ promoted_type_id = H5I_register(H5I_DATATYPE, promoted_type, FALSE);
+
+ /* Find the conversion function */
+ if (NULL == (tpath = H5T_path_find(type, promoted_type, NULL, NULL, H5P_LST_DATASET_XFER_g, FALSE)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to find type info")
+ if (FAIL == (H5T_convert(tpath, type_id, promoted_type_id, 1, (size_t)0, (size_t)0, value_buf, NULL, H5P_LST_DATASET_XFER_g)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCONVERT, FAIL, "can't convert value")
+
+ if (NULL == (tpath = H5T_path_find(query_type, promoted_type, NULL, NULL, H5P_LST_DATASET_XFER_g, FALSE)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to find type info")
+ if (FAIL == (H5T_convert(tpath, query_type_id, promoted_type_id, 1, (size_t)0, (size_t)0, query_value_buf, NULL, H5P_LST_DATASET_XFER_g)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCONVERT, FAIL, "can't convert query value")
+
+ /* Could also use BOOST preprocessor for that but not really nice */
+ switch (match_type) {
+ case H5Q_NATIVE_INT_MATCH_CHAR:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, char, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_SHORT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, short, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_INT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, int, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_LONG:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, long, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_LLONG:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, long long, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_FLOAT_MATCH_FLOAT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, float, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_FLOAT_MATCH_DOUBLE:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, double, value_buf, query_value_buf);
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "unsupported/unrecognized datatype")
+ break;
+ }
+
+ *result = query_result;
+
+done:
+ H5MM_free(value_buf);
+ H5MM_free(query_value_buf);
+
+ /* Free temporary IDs */
+ H5I_remove(type_id);
+ H5I_remove(query_type_id);
+ H5I_remove(promoted_type_id);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_data_elem() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_attr_name
+ *
+ * Purpose: Private function for H5Qapply (attribute name).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_attr_name(H5Q_t *query, hbool_t *result, const char *name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(query);
+ HDassert(query->query.select.type == H5Q_TYPE_ATTR_NAME);
+
+ *result = (0 == HDstrcmp(name, query->query.select.elem.attr_name.name));
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_attr_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_link_name
+ *
+ * Purpose: Private function for H5Qapply (link name).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_link_name(H5Q_t *query, hbool_t *result, const char *name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(query);
+ HDassert(query->query.select.type == H5Q_TYPE_LINK_NAME);
+
+ *result = (0 == HDstrcmp(name, query->query.select.elem.link_name.name));
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_link_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qencode
+ *
+ * Purpose: Given a query ID, serialize the query into buf.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qencode(hid_t query_id, void *buf, size_t *nalloc)
+{
+ H5Q_t *query;
+ herr_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x*z", query_id, buf, nalloc);
+
+ /* Check argument and retrieve object */
+ if(NULL == (query = (H5Q_t *)H5I_object_verify(query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(nalloc == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for buffer size")
+
+ /* Encode the query */
+ if((ret_value = H5Q_encode(query, (unsigned char *)buf, nalloc)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't encode query")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qencode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_encode
+ *
+ * Purpose: Private function for H5Qencode.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_encode(H5Q_t *query, unsigned char *buf, size_t *nalloc)
+{
+ size_t buf_size = 0;
+ herr_t ret_value = SUCCEED;
+ unsigned char *buf_ptr = buf;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(nalloc);
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->is_combined, sizeof(hbool_t));
+ if (query->is_combined) {
+ size_t l_buf_size = 0, r_buf_size = 0;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->query.combine.op, sizeof(H5Q_combine_op_t));
+ H5Q_encode(query->query.combine.l_query, buf_ptr, &l_buf_size);
+ buf_size += l_buf_size;
+ if (buf_ptr) buf_ptr += l_buf_size;
+ H5Q_encode(query->query.combine.r_query, buf_ptr, &r_buf_size);
+ buf_size += r_buf_size;
+ if (buf_ptr) buf_ptr += r_buf_size;
+ } else {
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->query.select.type, sizeof(H5Q_type_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->query.select.match_op, sizeof(H5Q_match_op_t));
+ switch (query->query.select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ size_t type_id_nalloc = 0;
+ H5T_t *type = query->query.select.elem.data_elem.type;
+ size_t type_size = query->query.select.elem.data_elem.type_size;
+ void *value_buf = query->query.select.elem.data_elem.value;
+
+ if (FAIL == H5T_encode(type, NULL, &type_id_nalloc))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't get encoding size for datatype");
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &type_id_nalloc, sizeof(size_t));
+ if (FAIL == H5T_encode(type, buf_ptr, &type_id_nalloc))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't encode datatype");
+ buf_size += type_id_nalloc;
+ if (buf_ptr) buf_ptr += type_id_nalloc;
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &type_size, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, value_buf, type_size);
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ size_t name_len = HDstrlen(query->query.select.elem.attr_name.name) + 1;
+ char *name = query->query.select.elem.attr_name.name;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &name_len, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, name, name_len);
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ size_t name_len = HDstrlen(query->query.select.elem.link_name.name) + 1;
+ char *name = query->query.select.elem.attr_name.name;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &name_len, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, name, name_len);
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ *nalloc = buf_size;
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_encode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qdecode
+ *
+ * Purpose: Deserialize the buffer and return a new query handle.
+ *
+ * Return: Success: query ID (non-negative)
+ *
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qdecode(const void *buf)
+{
+ H5Q_t *query;
+ hid_t ret_value; /* Return value */
+ const unsigned char *buf_ptr = (const unsigned char *) buf;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("i", "*x", buf);
+
+ /* Check args */
+ if(buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "empty buffer")
+
+ /* Create datatype by decoding buffer */
+ if(NULL == (query = H5Q_decode(&buf_ptr)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTDECODE, FAIL, "can't decode object")
+
+ /* Register the type and return the ID */
+ if((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "unable to register query")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qdecode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_decode
+ *
+ * Purpose: Private function for H5Qdecode.
+ *
+ * Return: Success: Pointer to the decoded query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_decode(const unsigned char **buf_ptr)
+{
+ H5Q_t *ret_value = NULL;
+ H5Q_t *query = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(*buf_ptr);
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ /* Set ref count */
+ query->ref_count = 1;
+
+ H5Q_decode_memcpy(&query->is_combined, sizeof(hbool_t), buf_ptr);
+ if (query->is_combined) {
+ H5Q_decode_memcpy(&query->query.combine.op, sizeof(H5Q_combine_op_t), buf_ptr);
+ query->query.combine.l_query = H5Q_decode(buf_ptr);
+ query->query.combine.r_query = H5Q_decode(buf_ptr);
+ } else {
+ H5Q_decode_memcpy(&query->query.select.type, sizeof(H5Q_type_t), buf_ptr);
+ H5Q_decode_memcpy(&query->query.select.match_op, sizeof(H5Q_match_op_t), buf_ptr);
+ switch (query->query.select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ size_t type_id_nalloc = 0;
+ H5T_t *type;
+ size_t type_size;
+ void *value_buf;
+
+ H5Q_decode_memcpy(&type_id_nalloc, sizeof(size_t), buf_ptr);
+ if (NULL == (type = H5T_decode(*buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode datatype");
+ query->query.select.elem.data_elem.type = type;
+ *buf_ptr += type_id_nalloc;
+
+ H5Q_decode_memcpy(&type_size, sizeof(size_t), buf_ptr);
+ query->query.select.elem.data_elem.type_size = type_size;
+ if (NULL == (value_buf = H5MM_malloc(type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL, "can't allocate value buffer")
+ H5Q_decode_memcpy(value_buf, type_size, buf_ptr);
+ query->query.select.elem.data_elem.value = value_buf;
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ size_t name_len;
+ char *name;
+
+ H5Q_decode_memcpy(&name_len, sizeof(size_t), buf_ptr);
+ if (NULL == (name = H5MM_malloc(name_len)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ H5Q_decode_memcpy(name, name_len, buf_ptr);
+ query->query.select.elem.attr_name.name = name;
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ size_t name_len;
+ char *name;
+
+ H5Q_decode_memcpy(&name_len, sizeof(size_t), buf_ptr);
+ if (NULL == (name = H5MM_malloc(name_len)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ H5Q_decode_memcpy(name, name_len, buf_ptr);
+ query->query.select.elem.link_name.name = name;
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ ret_value = query;
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_decode() */
diff --git a/src/H5Qprivate.h b/src/H5Qprivate.h
new file mode 100644
index 0000000..d9cc44e
--- /dev/null
+++ b/src/H5Qprivate.h
@@ -0,0 +1,100 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5Q module
+ */
+#ifndef _H5Qprivate_H
+#define _H5Qprivate_H
+
+/* Include package's public header */
+#include "H5Qpublic.h"
+
+/* Private headers needed by this file */
+#include "H5Tprivate.h"
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Data element */
+struct H5Q_data_elem {
+ H5T_t *type; /* type */
+ size_t type_size; /* type size */
+ void *value; /* value */
+};
+
+/* Attribute name */
+struct H5Q_attr_name {
+ char *name; /* name */
+};
+
+/* Link name */
+struct H5Q_link_name {
+ char *name; /* name */
+};
+
+/* Query */
+typedef struct H5Q_t H5Q_t;
+
+/* Combine query */
+struct H5Q_combine {
+ H5Q_combine_op_t op; /* op */
+ H5Q_t *l_query; /* left op query */
+ H5Q_t *r_query; /* right op query */
+};
+
+/* Select query */
+struct H5Q_select {
+ H5Q_type_t type; /* type */
+ H5Q_match_op_t match_op; /* match op */
+ union {
+ struct H5Q_data_elem data_elem;
+ struct H5Q_attr_name attr_name;
+ struct H5Q_link_name link_name;
+ } elem;
+};
+
+/* Query */
+struct H5Q_t {
+ unsigned ref_count; /* ref count */
+ hbool_t is_combined;
+ union {
+ struct H5Q_select select;
+ struct H5Q_combine combine;
+ } query;
+};
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+H5_DLL herr_t H5Q_init(void);
+H5_DLL H5Q_t *H5Q_create(H5Q_type_t query_type, H5Q_match_op_t match_op, ...);
+H5_DLL herr_t H5Q_close(H5Q_t *query);
+H5_DLL H5Q_t *H5Q_combine(H5Q_t *query1, H5Q_combine_op_t combine_op, H5Q_t *query2);
+H5_DLL herr_t H5Q_apply(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem);
+
+H5_DLL herr_t H5Q_encode(H5Q_t *query, unsigned char *buf, size_t *nalloc);
+H5_DLL H5Q_t *H5Q_decode(const unsigned char **buf);
+
+#endif /* _H5Qprivate_H */
diff --git a/src/H5Qpublic.h b/src/H5Qpublic.h
new file mode 100644
index 0000000..f3dd48f
--- /dev/null
+++ b/src/H5Qpublic.h
@@ -0,0 +1,83 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+ * H5Q module.
+ */
+#ifndef _H5Qpublic_H
+#define _H5Qpublic_H
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/* Query type */
+typedef enum H5Q_type_t {
+ H5Q_TYPE_DATA_ELEM, /* selects data elements */
+ H5Q_TYPE_ATTR_NAME, /* selects attributes */
+ H5Q_TYPE_LINK_NAME /* selects objects */
+} H5Q_type_t;
+
+/* Query match conditions */
+typedef enum H5Q_match_op_t {
+ H5Q_MATCH_EQUAL, /* equal */
+ H5Q_MATCH_NOT_EQUAL, /* not equal */
+ H5Q_MATCH_LESS_THAN, /* less than */
+ H5Q_MATCH_GREATER_THAN /* greater than */
+} H5Q_match_op_t;
+
+/* Query combine operators */
+typedef enum H5Q_combine_op_t {
+ H5Q_COMBINE_AND,
+ H5Q_COMBINE_OR
+} H5Q_combine_op_t;
+
+/********************/
+/* Public Variables */
+/********************/
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function prototypes */
+H5_DLL hid_t H5Qcreate(H5Q_type_t query_type, H5Q_match_op_t match_op, ...);
+H5_DLL herr_t H5Qclose(hid_t query_id);
+H5_DLL hid_t H5Qcombine(hid_t query_id1, H5Q_combine_op_t combine_op, hid_t query_id2);
+H5_DLL herr_t H5Qapply(hid_t query_id, hbool_t *result, hid_t type_id, const void *elem);
+/* or return dataspace and have
+ * hid_t H5Qapply(query_id, result, enum data_elem/link/attr, nelem, void*);
+ */
+
+/* Encode / decode */
+H5_DLL herr_t H5Qencode(hid_t query_id, void *buf, size_t *nalloc);
+H5_DLL hid_t H5Qdecode(const void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5Qpublic_H */
diff --git a/src/H5RC.c b/src/H5RC.c
new file mode 100644
index 0000000..008e709
--- /dev/null
+++ b/src/H5RC.c
@@ -0,0 +1,732 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ * August, 2013
+ *
+ * Purpose: Read Context APIs to support Exascale FastForward
+ * functionality.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5RC_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
+#include "H5RCprivate.h" /* Read Contexts */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod_client.h" /* IOD VOL plugin */
+
+#ifdef H5_HAVE_EFF
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5RC_t struct */
+H5FL_DEFINE(H5RC_t);
+
+/* Dataspace ID class */
+static const H5I_class_t H5I_RC_CLS[1] = {{
+ H5I_RC, /* ID class value */
+ 0, /* Class flags */
+ 2, /* # of reserved IDs for class */
+ (H5I_free_t)H5RC_close, /* Callback routine for closing objects of this class */
+ NULL /* Callback routine for closing auxilary objects of this class */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RC_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RC_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 H5RC_init() */
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5RC_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5RC_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5RC_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Initialize the atom group for the RC IDs */
+ if(H5I_register_type(H5I_RC_CLS) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RC_init_interface() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RC_term_interface
+ PURPOSE
+ Terminate various H5RC objects
+ USAGE
+ void H5RC_term_interface()
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5RC_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_interface_initialize_g) {
+ if((n = H5I_nmembers(H5I_RC))) {
+ H5I_clear_type(H5I_RC, FALSE, FALSE);
+ } /* end if */
+ else {
+ /* Free data types */
+ H5I_dec_type_ref(H5I_RC);
+
+ /* Shut down interface */
+ H5_interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5RC_term_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_rcapl_version_request
+ *
+ * Purpose: Set the request type for acquring the container version,
+ * whether it has to be exactly the one requested (H5RC_EXACT),
+ * the lowest available greater than the one requested if it is
+ * not available (H5RC_NEXT), or the last one available ((H5RC_LAST).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_rcapl_version_request(hid_t rcapl_id, H5RC_request_t acquire_req)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iRc", rcapl_id, acquire_req);
+
+ if(H5RC_LAST < acquire_req)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "Acquire request can be either H5RC_EXACT, H5RC_NEXT, or H5RC_LAST");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(rcapl_id, H5P_RC_ACQUIRE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set property */
+ if(H5P_set(plist, H5RC_ACQUIRE_CV_REQUEST_NAME, &acquire_req) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set acquire request");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_rcapl_version_request() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_rcapl_version_request
+ *
+ * Purpose: Get the request type for acquring the container version,
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_rcapl_version_request(hid_t rcapl_id, H5RC_request_t *acquire_req)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Rc", rcapl_id, acquire_req);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(rcapl_id, H5P_RC_ACQUIRE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ if(acquire_req) {
+ /* Get property */
+ if(H5P_get(plist, H5RC_ACQUIRE_CV_REQUEST_NAME, acquire_req) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get acquire request");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_rcapl_version_request() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCcreate
+ *
+ * Purpose: Wraps an hid_t around a container version and a file ID.
+ * The user is responsible for making sure the container version
+ * is acquired.
+ *
+ * Return: Success: The ID for a new read context.
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5RCcreate(hid_t file_id, uint64_t c_version)
+{
+ void *file = NULL;
+ H5VL_t *vol_plugin = NULL;
+ H5RC_t *rc = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("i", "iIl", file_id, c_version);
+
+ /* get the file object */
+ if(NULL == (file = (void *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* create a new read context object */
+ if(NULL == (rc = H5RC_create(file, c_version)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create read context")
+
+ /* Get an atom for the event queue with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register2(H5I_RC, rc, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize read context handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCcreate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RC_create
+ *
+ * Purpose: Private routine for H5RCcreate
+ *
+ * Return: Success: RC structure
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+H5RC_t *
+H5RC_create(void *file, uint64_t c_version)
+{
+ H5RC_t *rc = NULL;
+ H5RC_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* allocate read context struct */
+ if(NULL == (rc = H5FL_CALLOC(H5RC_t)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate read context structure")
+
+ rc->file = (H5VL_iod_file_t *)file;
+ rc->c_version = c_version;
+
+ rc->req_info.request = NULL;
+ rc->req_info.head = NULL;
+ rc->req_info.tail = NULL;
+ rc->req_info.num_req = 0;
+
+ /* set return value */
+ ret_value = rc;
+
+done:
+ if(!ret_value && rc)
+ rc = H5FL_FREE(H5RC_t, rc);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RC_create() */
+
+herr_t
+H5RCget_version(hid_t rc_id, uint64_t *c_version)
+{
+ H5RC_t *rc = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Il", rc_id, c_version);
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rc_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Read Context ID")
+
+ *c_version = rc->c_version;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCacquire
+ *
+ * Purpose: Acquires a read context from a container for a container
+ * version c_version. The user can specify options to
+ * what container version to get if the one being asked for
+ * is not available.
+ *
+ * Return: Success: RC ID
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5RCacquire(hid_t file_id, uint64_t *c_version,
+ hid_t rcapl_id, hid_t estack_id)
+{
+ void *file = NULL;
+ H5VL_t *vol_plugin = NULL;
+ H5RC_t *rc = NULL;
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ hid_t rc_id = FAIL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("i", "i*Ilii", file_id, c_version, rcapl_id, estack_id);
+
+ /* get the file object */
+ if(NULL == (file = (void *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == rcapl_id)
+ rcapl_id = H5P_RC_ACQUIRE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(rcapl_id, H5P_RC_ACQUIRE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not read context acquire property list")
+
+ /* create a new read context object with the provided container
+ version. The container version associated with the RC object
+ might be changed if the version is not available for read. */
+ if(NULL == (rc = H5RC_create(file, *c_version)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create read context")
+ /* Get an atom for the event queue with the VOL information as the auxilary struct*/
+ if((rc_id = H5I_register2(H5I_RC, rc, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize read context handle")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_rc_acquire((H5VL_iod_file_t *)file, rc, c_version, rcapl_id, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a read context on container");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack")
+ }
+
+ ret_value = rc_id;
+
+done:
+ if(ret_value < 0 && rc_id) {
+ if(H5I_dec_app_ref(rc_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close read context")
+ }
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCacquire() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCrelease
+ *
+ * Purpose: Releases a previously acquired container version. Does not
+ * close the RC object (i.e. user has to call H5RCclose()).
+ *
+ * Return: Success: Non-Negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RCrelease(hid_t rc_id , hid_t estack_id)
+{
+ H5RC_t *rc = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", rc_id, estack_id);
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rc_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Read Context ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(rc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_rc_release(rc, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a release on a read context on container");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCrelease() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCpersist
+ *
+ * Purpose: Persists a previously acquired container version.
+ *
+ * Return: Success: Non-Negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RCpersist(hid_t rc_id , hid_t estack_id)
+{
+ H5RC_t *rc = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", rc_id, estack_id);
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rc_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Read Context ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(rc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_rc_persist(rc, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a persist on a read context on container");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCpersist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCsnapshot
+ *
+ * Purpose: Creates a permanently visible snapshot of a container state.
+ *
+ * Return: Success: Non-Negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RCsnapshot(hid_t rc_id , const char *snapshot_name, hid_t estack_id)
+{
+ H5RC_t *rc = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*si", rc_id, snapshot_name, estack_id);
+
+ /* Check arguments */
+ if(!snapshot_name || !*snapshot_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid snapshot name")
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rc_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Read Context ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(rc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_rc_snapshot(rc, snapshot_name, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a snapshot on a read context on container");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCsnapshot() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RCclose
+ *
+ * Purpose: Closes the specified read context ID. The ID will no longer be
+ * valid for accessing the read context.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RCclose(hid_t rc_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", rc_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(rc_id,H5I_RC))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an read context ID")
+
+ if(H5I_dec_app_ref(rc_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close read context")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5RCclose() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5RC_close
+ *
+ * Purpose: Closes the specified read context ID. The ID will no longer be
+ * valid for accessing the read context.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RC_close(H5RC_t *rc)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(rc->req_info.num_req) {
+ H5VL_iod_request_t *cur_req = rc->req_info.head;
+ H5VL_iod_request_t *next_req = NULL;
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ while(cur_req) {
+ next_req = cur_req->trans_next;
+
+ /* remove the current request from the linked list */
+ prev = cur_req->trans_prev;
+ next = cur_req->trans_next;
+ if (prev) {
+ if (next) {
+ prev->trans_next = next;
+ next->trans_prev = prev;
+ }
+ else {
+ prev->trans_next = NULL;
+ rc->req_info.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->trans_prev = NULL;
+ rc->req_info.head = next;
+ }
+ else {
+ rc->req_info.head = NULL;
+ rc->req_info.tail = NULL;
+ }
+ }
+
+ cur_req->trans_prev = NULL;
+ cur_req->trans_next = NULL;
+
+ rc->req_info.num_req --;
+
+ H5VL_iod_request_decr_rc(cur_req);
+
+ cur_req = next_req;
+ }
+ HDassert(0 == rc->req_info.num_req);
+ }
+
+ rc = H5FL_FREE(H5RC_t, rc);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5RC_close() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5RCprivate.h b/src/H5RCprivate.h
new file mode 100644
index 0000000..a280ff9
--- /dev/null
+++ b/src/H5RCprivate.h
@@ -0,0 +1,70 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5RC module
+ */
+#ifndef _H5RCprivate_H
+#define _H5RCprivate_H
+
+/* Include package's public header */
+#include "H5RCpublic.h"
+
+/* Private headers needed by this file */
+#include "H5private.h" /* Generic Functions */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5VLprivate.h" /* VOL plugins */
+
+#ifdef H5_HAVE_EFF
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Request and Linked list info used in transactions and read contexts
+ to track dependencies. */
+typedef struct H5VL_iod_req_info_t {
+ struct H5VL_iod_request_t *request;
+ struct H5VL_iod_request_t *head;
+ struct H5VL_iod_request_t *tail;
+ size_t num_req;
+} H5VL_iod_req_info_t;
+
+/* the client Read Context struct */
+typedef struct H5RC_t {
+ H5VL_iod_req_info_t req_info; /* must be first */
+ struct H5VL_iod_file_t *file;
+ uint64_t c_version;
+} H5RC_t;
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+herr_t H5RC_init(void);
+
+H5_DLL H5RC_t *H5RC_create(void *file, uint64_t c_version);
+H5_DLL herr_t H5RC_close(H5RC_t *rcxt);
+
+#endif /* H5_HAVE_EFF */
+
+#endif /* _H5RCprivate_H */
diff --git a/src/H5RCpublic.h b/src/H5RCpublic.h
new file mode 100644
index 0000000..4fca5cb
--- /dev/null
+++ b/src/H5RCpublic.h
@@ -0,0 +1,74 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+ * H5RC module.
+ */
+#ifndef _H5RCpublic_H
+#define _H5RCpublic_H
+
+/* System headers needed by this file */
+
+/* Public headers needed by this file */
+
+/*****************/
+/* Public Macros */
+/*****************/
+#define H5RC_ACQUIRE_CV_REQUEST_NAME "acquire_request_name"
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+typedef enum H5RC_request_t{
+ H5RC_EXACT, /* default */
+ H5RC_PREV,
+ H5RC_NEXT,
+ H5RC_LAST
+} H5RC_request_t;
+
+/********************/
+/* Public Variables */
+/********************/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef H5_HAVE_EFF
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+/* API wrappers */
+H5_DLL hid_t H5RCcreate(hid_t file_id, uint64_t container_version);
+H5_DLL herr_t H5RCget_version(hid_t rcxt_id, uint64_t *c_version);
+H5_DLL hid_t H5RCacquire(hid_t file_id, /*IN/OUT*/ uint64_t *container_version,
+ hid_t rcapl_id, hid_t estack_id);
+H5_DLL herr_t H5RCrelease(hid_t rcxt_id , hid_t estack_id);
+H5_DLL herr_t H5RCpersist(hid_t rcxt_id, hid_t estack_id);
+H5_DLL herr_t H5RCsnapshot(hid_t rcxt_id, const char *snapshot_name, hid_t estack_id);
+H5_DLL herr_t H5RCclose(hid_t rcxt_id);
+
+H5_DLL herr_t H5Pset_rcapl_version_request(hid_t rcapl_id, H5RC_request_t acquire_req);
+H5_DLL herr_t H5Pget_rcapl_version_request(hid_t rcapl_id, H5RC_request_t *acquire_req);
+
+#endif /* H5_HAVE_EFF */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5RCpublic_H */
diff --git a/src/H5S.c b/src/H5S.c
index bcaea8d..f070089 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -55,8 +55,6 @@
static herr_t H5S_set_extent_simple (H5S_t *space, unsigned rank,
const hsize_t *dims, const hsize_t *max);
static htri_t H5S_is_simple(const H5S_t *sdim);
-static herr_t H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc);
-static H5S_t *H5S_decode(const unsigned char *buf);
/*********************/
@@ -1502,7 +1500,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc)
{
size_t extent_size; /* Size of serialized dataspace extent */
@@ -1618,7 +1616,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5S_t*
+H5S_t*
H5S_decode(const unsigned char *buf)
{
H5S_t *ds;
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index c97c9b6..accc3a5 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -8856,3 +8856,79 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_get_seq_list() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_is_regular
+ PURPOSE
+ Check if hyperslab selection is a regular selection
+ RETURNS
+ TRUE/FALSE/FAIL
+--------------------------------------------------------------------------*/
+htri_t
+H5Sselect_is_regular(hid_t space_id)
+{
+ H5S_t *space; /* dataspace to modify */
+ htri_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "i", space_id);
+
+ /* Check args and all the boring stuff. */
+ if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
+
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS)
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "not a hyperslab selection")
+
+ if(space->select.sel_info.hslab->diminfo_valid)
+ ret_value = TRUE;
+ else
+ ret_value = FALSE;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sget_reg_hyperslab_params
+ PURPOSE
+ retrieve the start, stride, count, block arrays of a regular
+ hyperslab selection
+ RETURNS
+ TRUE/FALSE/FAIL
+--------------------------------------------------------------------------*/
+herr_t
+H5Sget_reg_hyperslab_params(hid_t space_id, hsize_t start[], hsize_t stride[],
+ hsize_t count[], hsize_t block[])
+{
+ H5S_t *space = NULL; /* Dataspace to get selection of */
+ const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ unsigned ndims; /* Rank of the dataspace */
+ unsigned u;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "i*h*h*h*h", space_id, start, stride, count, block);
+
+ /* Check args */
+ if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(!space->select.sel_info.hslab->diminfo_valid)
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "not a regular hyperslab selection")
+
+ diminfo = space->select.sel_info.hslab->opt_diminfo;
+ ndims = space->extent.rank;
+
+ for(u=0 ; u<ndims; u++) {
+ start[u] = diminfo[u].start;
+ stride[u] = diminfo[u].stride;
+ count[u] = diminfo[u].count;
+ block[u] = diminfo[u].block;
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 0e67af1..bee64a2 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -267,6 +267,14 @@ H5_DLL hsize_t H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter);
H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter);
+H5_DLL herr_t H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc);
+H5_DLL H5S_t *H5S_decode(const unsigned char *buf);
+
+H5_DLL herr_t H5S_get_offsets(const H5S_t *space, size_t elmt_size, size_t nelmts,
+ hsize_t **_off, size_t **_len, size_t *_num_entries);
+H5_DLL uint64_t H5S_checksum(const void *buf, size_t elmt_size, size_t nelmts,
+ const H5S_t *space);
+
#ifdef H5_HAVE_PARALLEL
/* Global vars whose value comes from environment variable */
/* (Defined in H5S.c) */
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 6e87a65..f4f28f6 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -113,6 +113,13 @@ H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op,
const hsize_t _stride[],
const hsize_t count[],
const hsize_t _block[]);
+H5_DLL htri_t H5Sselect_is_regular(hid_t space_id);
+H5_DLL herr_t H5Sget_reg_hyperslab_params(hid_t space_id,
+ hsize_t start[],
+ hsize_t stride[],
+ hsize_t count[],
+ hsize_t block[]);
+
/* #define NEW_HYPERSLAB_API */
/* Note that these haven't been working for a while and were never
* publicly released - QAK */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 44688b6..2400697 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -31,6 +31,9 @@
#include "H5Spkg.h" /* Dataspaces */
#include "H5VMprivate.h" /* Vector and array functions */
#include "H5WBprivate.h" /* Wrapped Buffers */
+#ifdef H5_HAVE_EFF
+#include "mchecksum.h" /* Mercury Checksum library */
+#endif /* H5_HAVE_EFF */
/* Local functions */
#ifdef LATER
@@ -2053,3 +2056,160 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_fill() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_get_offsets
+ *
+ * Purpose: Returns an offset/length pair array for a corresponding
+ * dataspace selecton.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_get_offsets(const H5S_t *space, size_t elmt_size, size_t nelmts,
+ hsize_t **_off, size_t **_len, size_t *_num_entries)
+{
+ H5S_sel_iter_t iter; /* Memory selection iteration info */
+ hbool_t iter_init = 0; /* Memory selection iteration info has been initialized */
+ size_t curr_seq; /* Current memory sequence to operate on */
+ size_t nseq; /* Number of sequences generated in the file */
+ hsize_t *off = NULL;
+ size_t *len = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (off = (hsize_t *)calloc(H5D_IO_VECTOR_SIZE, sizeof(hsize_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
+ if(NULL == (len = (size_t *)calloc(H5D_IO_VECTOR_SIZE, sizeof(size_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
+
+ /* Check for only one element in selection */
+ if(nelmts == 1) {
+ if(H5S_SELECT_OFFSET(space, off) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve memory selection offset");
+
+ /* Set up necessary information for I/O operation */
+ nseq = 1;
+ *off *= elmt_size;
+ *len = elmt_size;
+ } /* end if */
+ else {
+ size_t nelem; /* Number of elements used in sequences */
+ size_t n = 2;
+
+ /* Initialize iterator */
+ if(H5S_select_iter_init(&iter, space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ iter_init = 1; /* Memory selection iteration info has been initialized */
+
+ /* Initialize sequence counts */
+ curr_seq = 0;
+ nseq = 0;
+
+ /* Loop, until all bytes are processed */
+ while(nelmts > 0) {
+ /* Get sequences for selection */
+ if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, H5D_IO_VECTOR_SIZE, nelmts, &nseq,
+ &nelem, &off[curr_seq], &len[curr_seq]) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
+
+ /* check if more sequences are needed and extend the arrays if yes */
+ nelmts -= nelem;
+ curr_seq += nseq;
+
+ if(nelmts) {
+ HDassert(nseq == H5D_IO_VECTOR_SIZE);
+ if(NULL == (off = (hsize_t *)realloc(off, n * sizeof(hsize_t) * H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
+ if(NULL == (len = (size_t *)realloc(len, n * sizeof(size_t) * H5D_IO_VECTOR_SIZE)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O length vector array");
+ }
+ n ++;
+ } /* end while */
+ } /* end else */
+
+ *_off = off;
+ *_len = len;
+ *_num_entries = curr_seq;
+
+done:
+ /* Release memory selection iterator */
+ if(iter_init)
+ if(H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_get_offsets() */
+
+#ifdef H5_HAVE_EFF
+uint64_t
+H5S_checksum(const void *buf, size_t elmt_size, size_t nelmts, const H5S_t *space)
+{
+ H5S_sel_iter_t iter; /* Memory selection iteration info */
+ hbool_t iter_init = 0; /* Memory selection iteration info has been initialized */
+ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets in memory */
+ hsize_t *off = NULL; /* Pointer to sequence offsets in memory */
+ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths in memory */
+ size_t *len = NULL; /* Pointer to sequence lengths in memory */
+ size_t nseq; /* Number of sequences generated */
+ size_t nelem; /* Number of elements used in sequences */
+ size_t i;
+ const uint8_t *p = (const uint8_t *)buf;
+ const char *hash_method = "crc64";
+ size_t hash_size;
+ mchecksum_object_t checksum;
+ uint64_t ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ len = _len;
+ off = _off;
+
+ /* Initialize iterator */
+ if(H5S_select_iter_init(&iter, space, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, 0, "unable to initialize selection iterator")
+ iter_init = 1;
+
+ nseq = 0;
+
+ /* Initialize checksum */
+ mchecksum_init(hash_method, &checksum);
+
+ /* Loop, until all bytes are processed */
+ while(nelmts > 0) {
+ /* Get sequences for selection */
+ if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, H5D_IO_VECTOR_SIZE, nelmts, &nseq,
+ &nelem, off, len) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed");
+
+ for(i=0 ; i<nseq ; i++) {
+ mchecksum_update(checksum, p+off[i], len[i]);
+ }
+ nelmts -= nelem;
+ } /* end while */
+
+ /* Get size of checksum */
+ hash_size = mchecksum_get_size(checksum);
+
+ assert(hash_size == sizeof(uint64_t));
+
+ /* get checksum value */
+ mchecksum_get(checksum, &ret_value, hash_size, 1);
+
+ /* Destroy checksum */
+ mchecksum_destroy(checksum);
+
+done:
+ /* Release memory selection iterator */
+ if(iter_init)
+ if(H5S_SELECT_ITER_RELEASE(&iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, 0, "unable to release selection iterator")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_checksum */
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5T.c b/src/H5T.c
index 479a0a2..1a44105 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1750,6 +1750,7 @@ herr_t
H5Tclose(hid_t type_id)
{
H5T_t *dt; /* Pointer to datatype to close */
+ H5VL_t *vol_plugin = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -1761,6 +1762,15 @@ H5Tclose(hid_t type_id)
if(H5T_STATE_IMMUTABLE == dt->shared->state)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")
+ /* get the plugin pointer -
+ * if it exists, then we know that the datatype is committed,
+ * so we attach synchronous event q to it so it can pass through the VL layer. */
+ if (NULL != (vol_plugin = (H5VL_t *)H5I_get_aux(type_id))) {
+ /* set the event queue and dxpl IDs to be passed on to the VOL layer */
+ vol_plugin->close_estack_id = H5_EVENT_STACK_NULL;
+ vol_plugin->close_dxpl_id = H5AC_dxpl_id;
+ }
+
/* When the reference count reaches zero the resources are freed */
if(H5I_dec_app_ref(type_id) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id")
diff --git a/src/H5TR.c b/src/H5TR.c
new file mode 100644
index 0000000..8bdc8b5
--- /dev/null
+++ b/src/H5TR.c
@@ -0,0 +1,829 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ * August, 2013
+ *
+ * Purpose: Transaction APIs to support Exascale FastForward
+ * functionality.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5TR_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5RCprivate.h" /* Read Contexts */
+#include "H5TRprivate.h" /* Transactions */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod_client.h" /* IOD VOL plugin */
+
+#ifdef H5_HAVE_EFF
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5TR_t struct */
+H5FL_DEFINE(H5TR_t);
+
+/* Dataspace ID class */
+static const H5I_class_t H5I_TR_CLS[1] = {{
+ H5I_TR, /* ID class value */
+ 0, /* Class flags */
+ 2, /* # of reserved IDs for class */
+ (H5I_free_t)H5TR_close, /* Callback routine for closing objects of this class */
+ NULL /* Callback routine for closing auxilary objects of this class */
+}};
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TR_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TR_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 H5TR_init() */
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5TR_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5TR_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5TR_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Initialize the atom group for the TR IDs */
+ if(H5I_register_type(H5I_TR_CLS) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5TR_init_interface() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5TR_term_interface
+ PURPOSE
+ Terminate various H5TR objects
+ USAGE
+ void H5TR_term_interface()
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5TR_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_interface_initialize_g) {
+ if((n = H5I_nmembers(H5I_TR))) {
+ H5I_clear_type(H5I_TR, FALSE, FALSE);
+ } /* end if */
+ else {
+ /* Free data types */
+ H5I_dec_type_ref(H5I_TR);
+
+ /* Shut down interface */
+ H5_interface_initialize_g = 0;
+ n = 1; /*H5I*/
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5TR_term_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_trspl_num_peers
+ *
+ * Purpose: Set the number of peers that will call H5TRstart for a
+ * transaction. If num_peers=0, the application has appointed a
+ * transaction leader to signal the start and finish of the
+ * transaction, and to coordinate with processes participating in the
+ * transaction regarding when they can begin updating and when their
+ * updates are done. When this is the case, only one process (the
+ * transaction leader) can call H5TRstart and H5TRfinish for the given
+ * transaction_num. This mode of operation is typical for
+ * tightly-coupled applications. If num_peers>0, the I/O stack (in
+ * particular, IOD) will track the status of the transaction. All
+ * num_peers processes participating in the transaction must call
+ * H5TRstart with the same values for num_peers and transaction_num.
+ * As each participating process is done with their updates in the
+ * transaction, they individually call H5TRfinish for this
+ * transaction_num. When all num_peers processes have called
+ * H5TRfinish for this transaction_num, the I/O stack detects that the
+ * transaction is finished and updates appear atomically when all
+ * lower-numbered transactions are finished, aborted, or skipped.
+ * This mode of operation is typical for loosely-coupled applications.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_trspl_num_peers(hid_t trspl_id, unsigned num_peers)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iIu", trspl_id, num_peers);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(trspl_id, H5P_TR_START)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set property */
+ if(H5P_set(plist, H5TR_START_NUM_PEERS_NAME, &num_peers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set num peers in transaction");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_trspl_num_peers() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_trspl_num_peers
+ *
+ * Purpose: Get the number of peers that will call H5TRstart for a
+ * transaction.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_trspl_num_peers(hid_t trspl_id, unsigned *num_peers)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Iu", trspl_id, num_peers);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(trspl_id, H5P_TR_START)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set property */
+ if(H5P_get(plist, H5TR_START_NUM_PEERS_NAME, num_peers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get num peers in transaction");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_trspl_num_peers() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRcreate
+ *
+ * Purpose: Wraps an hid_t around a transaction number, a file ID,
+ * and a read context ID on that file that operations using
+ * the created transaction will read from.
+ *
+ * Return: Success: The ID for a new transaction.
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5TRcreate(hid_t file_id, hid_t rc_id, uint64_t trans_num)
+{
+ void *file = NULL;
+ H5VL_t *vol_plugin = NULL;
+ H5TR_t *tr = NULL;
+ H5RC_t *rc = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("i", "iiIl", file_id, rc_id, trans_num);
+
+ /* get the file object */
+ if(NULL == (file = (void *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+ /* get the Read Context object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rc_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a read context ID")
+
+ /* create a new transaction object */
+ if(NULL == (tr = H5TR_create(file, rc, trans_num)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create transaction object")
+
+ /* Get an atom for the event queue with the VOL information as the auxilary struct*/
+ if((ret_value = H5I_register2(H5I_TR, tr, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize transaction handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRcreate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TR_create
+ *
+ * Purpose: Private version for H5TRcreate.
+ *
+ * Return: Success: Transaction struct.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+H5TR_t *
+H5TR_create(void *file, H5RC_t *rc, uint64_t trans_num)
+{
+ H5TR_t *tr = NULL;
+ H5TR_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* allocate transaction struct */
+ if(NULL == (tr = H5FL_CALLOC(H5TR_t)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate top transaction structure")
+
+ tr->file = (H5VL_iod_file_t *)file;
+ tr->c_version = rc->c_version;
+ tr->trans_num = trans_num;
+
+ tr->req_info.request = NULL;
+ tr->req_info.head = NULL;
+ tr->req_info.tail = NULL;
+ tr->req_info.num_req = 0;
+
+ /* set return value */
+ ret_value = tr;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5TR_create() */
+
+herr_t
+H5TRget_trans_num(hid_t trans_id, uint64_t *trans_num)
+{
+ H5TR_t *tr = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Il", trans_id, trans_num);
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a transaction ID")
+
+ *trans_num = tr->trans_num;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5TRget_trans_num */
+
+herr_t
+H5TRget_version(hid_t trans_id, uint64_t *c_version)
+{
+ H5TR_t *tr = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Il", trans_id, c_version);
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a transaction ID")
+
+ *c_version = tr->c_version;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5TRget_version */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRstart
+ *
+ * Purpose: Starts a transaction that has been created with H5TRcreate.
+ * If the operation fails, the user is still reponsible to call
+ * H5TRclose() on the returned value to free resources.
+ *
+ * Return: Success: Non-Negative.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRstart(hid_t tr_id, hid_t trspl_id, hid_t estack_id)
+{
+ H5TR_t *tr = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iii", tr_id, trspl_id, estack_id);
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(tr_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == trspl_id)
+ trspl_id = H5P_TR_START_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(trspl_id, H5P_TR_START))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not transaction start property list")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(tr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_tr_start(tr, trspl_id, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a transaction start");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRstart()*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRfinish
+ *
+ * Purpose: Finishes/Commits a transaction. If rcxt_id is not NULL,
+ * create a read context from the finished transaction number.
+ * If the finish fails, the user is still reponsible to call
+ * H5RCclose() on the rcxt_id and H5TRclose() on the tr_id
+ * to free resources.
+ *
+ * Return: Success: Non-Negative.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRfinish(hid_t tr_id, hid_t trfpl_id, hid_t *rcxt_id, hid_t estack_id)
+{
+ H5TR_t *tr = NULL;
+ H5RC_t *rc = NULL;
+ hbool_t acquire = FALSE;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "ii*ii", tr_id, trfpl_id, rcxt_id, estack_id);
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(tr_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == trfpl_id)
+ trfpl_id = H5P_TR_FINISH_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(trfpl_id, H5P_TR_FINISH))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not transaction finish property list")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(tr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ /* create a new read context object (if user requested it) with
+ the provided transaction number to finish */
+ if(rcxt_id) {
+ acquire = TRUE;
+
+ if(NULL == (rc = H5RC_create(tr->file, tr->trans_num)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create read context");
+ /* Get an atom for the event queue with the VOL information as the auxilary struct */
+ if((*rcxt_id = H5I_register2(H5I_RC, rc, vol_plugin, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize read context handle");
+ }
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_tr_finish(tr, acquire, trfpl_id, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a transaction finish");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRfinish()*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRset_dependency
+ *
+ * Purpose: Set a depedency between two transactions. Transaction
+ * associated with tr_id is declaring a dependency on transaction
+ * numbered trans_num. trans_num must be < the transaction number
+ * tr_id is associated with.
+ *
+ * Return: Success: Non-Negative.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRset_dependency(hid_t tr_id, uint64_t trans_num, hid_t estack_id)
+{
+ H5TR_t *tr = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iIli", tr_id, trans_num, estack_id);
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(tr_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(tr->trans_num <= trans_num)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "The dependent transaction must be higher than the one it depends on")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(tr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_tr_set_dependency(tr, trans_num, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a transaction set_dependency");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRset_dependency()*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRskip
+ *
+ * Purpose: Skip a sequence of transaction numbers from the container.
+ *
+ * Return: Success: Non-Negative.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRskip(hid_t file_id, uint64_t start_trans_num, uint64_t count, hid_t estack_id)
+{
+ void *file = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "iIlIli", file_id, start_trans_num, count, estack_id);
+
+ /* get the file object */
+ if(NULL == (file = (void *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_tr_skip((H5VL_iod_file_t *)file, start_trans_num, count, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a transaction skip");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRskip()*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRabort
+ *
+ * Purpose: Aborts a transaction
+ *
+ * Return: Success: Non-Negative.
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRabort(hid_t tr_id, hid_t estack_id)
+{
+ H5TR_t *tr = NULL;
+ H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ii", tr_id, estack_id);
+
+ /* get the plugin pointer */
+ if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(tr_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(tr_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if(H5VL_iod_tr_abort(tr, req) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "failed to request a transaction abort");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRabort()*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TRclose
+ *
+ * Purpose: Closes the specified transaction ID. The ID will no longer be
+ * valid for accessing the transaction.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TRclose(hid_t tr_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", tr_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(tr_id, H5I_TR))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an transaction ID")
+
+ if(H5I_dec_app_ref(tr_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close transaction")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5TRclose() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5TR_close
+ *
+ * Purpose: Frees the transaction struct.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5TR_close(H5TR_t *tr)
+{
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(tr->req_info.num_req) {
+ H5VL_iod_request_t *cur_req = tr->req_info.head;
+ H5VL_iod_request_t *next_req = NULL;
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ while(cur_req) {
+ next_req = cur_req->trans_next;
+
+ /* remove the current request from the linked list */
+ prev = cur_req->trans_prev;
+ next = cur_req->trans_next;
+ if (prev) {
+ if (next) {
+ prev->trans_next = next;
+ next->trans_prev = prev;
+ }
+ else {
+ prev->trans_next = NULL;
+ tr->req_info.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->trans_prev = NULL;
+ tr->req_info.head = next;
+ }
+ else {
+ tr->req_info.head = NULL;
+ tr->req_info.tail = NULL;
+ }
+ }
+
+ cur_req->trans_prev = NULL;
+ cur_req->trans_next = NULL;
+
+ tr->req_info.num_req --;
+
+ H5VL_iod_request_decr_rc(cur_req);
+
+ cur_req = next_req;
+ }
+ HDassert(0 == tr->req_info.num_req);
+ }
+
+ tr = H5FL_FREE(H5TR_t, tr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5TR_close() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5TRprivate.h b/src/H5TRprivate.h
new file mode 100644
index 0000000..70f5e5e
--- /dev/null
+++ b/src/H5TRprivate.h
@@ -0,0 +1,59 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 private information about the H5TR module
+ */
+#ifndef _H5TRprivate_H
+#define _H5TRprivate_H
+
+/* Include package's public header */
+#include "H5TRpublic.h"
+
+/* Private headers needed by this file */
+#include "H5RCprivate.h" /* Read Contexts */
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+#define H5TR_FINISH_ACQUIRE_NAME "acquire_after_finishing"
+
+#ifdef H5_HAVE_EFF
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* the transaction struct */
+typedef struct H5TR_t {
+ H5VL_iod_req_info_t req_info; /* must be first */
+ struct H5VL_iod_file_t *file;
+ uint64_t c_version;
+ uint64_t trans_num;
+} H5TR_t;
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+herr_t H5TR_init(void);
+
+H5_DLL H5TR_t *H5TR_create(void *file, H5RC_t *rc, uint64_t trans_num);
+H5_DLL herr_t H5TR_close(H5TR_t *tr);
+
+#endif /* H5_HAVE_EFF */
+#endif /* _H5TRprivate_H */
diff --git a/src/H5TRpublic.h b/src/H5TRpublic.h
new file mode 100644
index 0000000..c8ed982
--- /dev/null
+++ b/src/H5TRpublic.h
@@ -0,0 +1,71 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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
+ * H5TR module.
+ */
+#ifndef _H5TRpublic_H
+#define _H5TRpublic_H
+
+/* System headers needed by this file */
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/*****************/
+/* Public Macros */
+/*****************/
+#define H5TR_START_NUM_PEERS_NAME "number_of_peers_name"
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/********************/
+/* Public Variables */
+/********************/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef H5_HAVE_EFF
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+/* API wrappers */
+H5_DLL hid_t H5TRcreate(hid_t file_id, hid_t rc_id, uint64_t trans_num);
+H5_DLL herr_t H5TRget_trans_num(hid_t trans_id, uint64_t *trans_num);
+H5_DLL herr_t H5TRget_version(hid_t trans_id, uint64_t *c_version);
+H5_DLL herr_t H5TRstart(hid_t trans_id, hid_t trspl_id, hid_t estack_id);
+H5_DLL herr_t H5TRfinish(hid_t trans_id, hid_t trfpl_id, hid_t *rcntxt_id, hid_t estack_id);
+H5_DLL herr_t H5TRskip(hid_t file_id, uint64_t start_trans_num, uint64_t count, hid_t estack_id);
+H5_DLL herr_t H5TRset_dependency(hid_t trans_id, uint64_t trans_num, hid_t estack_id);
+H5_DLL herr_t H5TRabort(hid_t trans_id, hid_t estack_id);
+H5_DLL herr_t H5TRclose(hid_t trans_id);
+
+H5_DLL herr_t H5Pset_trspl_num_peers(hid_t trspl_id, unsigned num_peers);
+H5_DLL herr_t H5Pget_trspl_num_peers(hid_t trspl_id, unsigned *num_peers);
+
+#endif /* H5_HAVE_EFF */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5TRpublic_H */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index a483df7..9b1b1ae 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -1015,7 +1015,8 @@ H5T_close_datatype(void *type, H5VL_t *vol_plugin)
/* Close the datatype through the VOL*/
if (NULL != dt->vol_obj)
- if((ret_value = H5VL_datatype_close(dt->vol_obj, vol_plugin, H5AC_dxpl_id, H5_EVENT_STACK_NULL)) < 0)
+ if((ret_value = H5VL_datatype_close(dt->vol_obj, vol_plugin,
+ vol_plugin->close_dxpl_id, vol_plugin->close_estack_id)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close datatype")
done:
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 1a97f39..2dee5f5 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -32,8 +32,6 @@
#include "H5Tpkg.h" /* Datatypes */
/* Static local functions */
-static H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction,
- size_t *struct_align, size_t *offset, size_t *comp_size);
static H5T_t *H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
size_t *struct_align, size_t *offset, size_t *comp_size);
static H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction,
@@ -147,7 +145,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5T_t *
+H5T_t *
H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size)
{
H5T_t *dt; /* Datatype to make native */
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 217a0d6..7bf21ef 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -166,5 +166,9 @@ H5_DLL int H5T_get_offset(const H5T_t *dt);
/* Fixed-point functions */
H5_DLL H5T_sign_t H5T_get_sign(H5T_t const *dt);
+/* Native type function */
+H5_DLL H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction,
+ size_t *struct_align, size_t *offset, size_t *comp_size);
+
#endif /* _H5Tprivate_H */
diff --git a/src/H5VLint.c b/src/H5VLint.c
index 65250a1..b001cdf 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -39,6 +39,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Stacks */
#include "H5Iprivate.h" /* IDs */
#include "H5Ipkg.h" /* IDs Package header */
#include "H5Lprivate.h" /* Links */
@@ -391,6 +392,11 @@ H5VL_object_register(void *obj, H5I_type_t obj_type, H5VL_t *vol_plugin, hbool_t
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize group handle")
break;
+ case H5I_MAP:
+ if((ret_value = H5I_register2(obj_type, obj, vol_plugin, app_ref)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize map handle")
+ break;
+
case H5I_DATASET:
if((ret_value = H5I_register2(obj_type, obj, vol_plugin, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle")
@@ -407,6 +413,9 @@ H5VL_object_register(void *obj, H5I_type_t obj_type, H5VL_t *vol_plugin, hbool_t
case H5I_REFERENCE:
case H5I_VFL:
case H5I_VOL:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_ES:
case H5I_GENPROP_CLS:
case H5I_GENPROP_LST:
case H5I_ERROR_CLASS:
@@ -475,8 +484,10 @@ done:
*/
void *
H5VL_attr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -485,12 +496,28 @@ H5VL_attr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, co
if(NULL == vol_plugin->cls->attr_cls.create)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `attr create' method")
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* call the corresponding VOL create callback */
if(NULL == (ret_value = (vol_plugin->cls->attr_cls.create) (obj, loc_params, name, acpl_id,
- aapl_id, dxpl_id, H5_REQUEST_NULL)))
+ aapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed")
-
vol_plugin->nrefs ++;
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_create() */
@@ -512,8 +539,10 @@ done:
*/
void *
H5VL_attr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t aapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t aapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -521,11 +550,30 @@ H5VL_attr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, cons
/* check if the type specific corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->attr_cls.open)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `attr open' method")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* call the corresponding VOL open callback */
- if(NULL == (ret_value = (vol_plugin->cls->attr_cls.open) (obj, loc_params, name, aapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->attr_cls.open) (obj, loc_params, name, aapl_id,
+ dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "attribute open failed")
vol_plugin->nrefs ++;
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_open() */
@@ -546,17 +594,37 @@ done:
*-------------------------------------------------------------------------
*/
herr_t H5VL_attr_read(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, void *buf,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
if(NULL == vol_plugin->cls->attr_cls.read)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr read' method")
- if((ret_value = (vol_plugin->cls->attr_cls.read)(attr, mem_type_id, buf, dxpl_id, H5_REQUEST_NULL)) < 0)
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if((ret_value = (vol_plugin->cls->attr_cls.read)(attr, mem_type_id, buf,
+ dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "read failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_read() */
@@ -577,17 +645,37 @@ done:
*-------------------------------------------------------------------------
*/
herr_t H5VL_attr_write(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, const void *buf,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
if(NULL == vol_plugin->cls->attr_cls.write)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr write' method")
- if((ret_value = (vol_plugin->cls->attr_cls.write)(attr, mem_type_id, buf, dxpl_id, H5_REQUEST_NULL)) < 0)
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if((ret_value = (vol_plugin->cls->attr_cls.write)(attr, mem_type_id, buf,
+ dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "write failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_write() */
@@ -644,6 +732,8 @@ herr_t
H5VL_attr_get(void *obj, H5VL_t *vol_plugin, H5VL_attr_get_t get_type,
hid_t dxpl_id, hid_t estack_id, ...)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
va_list arguments; /* argument list passed from the API call */
herr_t ret_value = SUCCEED;
@@ -651,26 +741,28 @@ H5VL_attr_get(void *obj, H5VL_t *vol_plugin, H5VL_attr_get_t get_type,
if(NULL == vol_plugin->cls->attr_cls.get)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr get' method")
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->cls->attr_cls.get)(obj, get_type, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->cls->attr_cls.get)(obj, get_type, dxpl_id, req, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed")
va_end (arguments);
-#if 0
- /* if the get_type is a named datatype, attach the vol info to it */
- if(H5VL_ATTR_GET_TYPE == get_type) {
- hid_t *ret_id;
-
- va_start (arguments, estack_id);
- ret_id = va_arg (arguments, hid_t *);
- if(H5Tcommitted(*ret_id)) {
- /* attach VOL information to the ID */
- if (H5I_register_aux(*ret_id, vol_plugin, (H5I_free_t)H5VL_close) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID")
- }
- va_end (arguments);
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
}
-#endif
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_get() */
@@ -692,17 +784,36 @@ done:
*/
herr_t
H5VL_attr_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin,
- const char *attr_name, hid_t dxpl_id, hid_t UNUSED estack_id)
+ const char *attr_name, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
if(NULL == vol_plugin->cls->attr_cls.remove)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr remove' method")
- if((ret_value = (vol_plugin->cls->attr_cls.remove)(obj, loc_params, attr_name, dxpl_id, H5_REQUEST_NULL)) < 0)
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if((ret_value = (vol_plugin->cls->attr_cls.remove)(obj, loc_params, attr_name, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTDELETE, FAIL, "remove failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_remove() */
@@ -723,22 +834,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_attr_close(void *attr, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_attr_close(void *attr, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
/* if the VOL class does not implement a specific attr close
callback, try the object close */
- if(NULL == vol_plugin->cls->attr_cls.close){
+ if(NULL == vol_plugin->cls->attr_cls.close)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr close' method")
- /*
- if(H5VL_object_close(id, dxpl_id, estack_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object")
- */
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
}
- else if((ret_value = (vol_plugin->cls->attr_cls.close)(attr, dxpl_id, H5_REQUEST_NULL)) < 0)
+
+ if((ret_value = (vol_plugin->cls->attr_cls.close)(attr, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
vol_plugin->nrefs --;
@@ -748,6 +868,11 @@ H5VL_attr_close(void *attr, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED esta
vol_plugin = (H5VL_t *)H5MM_xfree(vol_plugin);
}
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_attr_close() */
@@ -770,9 +895,11 @@ done:
void *
H5VL_datatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
- void *ret_value = NULL; /* Return value */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -780,12 +907,28 @@ H5VL_datatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin
if(NULL == vol_plugin->cls->datatype_cls.commit)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `datatype commit' method")
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* call the corresponding VOL commit callback */
if(NULL == (ret_value = (vol_plugin->cls->datatype_cls.commit)
- (obj, loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id, dxpl_id, H5_REQUEST_NULL)))
+ (obj, loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "commit failed")
vol_plugin->nrefs ++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_datatype_commit() */
@@ -807,31 +950,40 @@ done:
*/
void *
H5VL_datatype_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t tapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t tapl_id, hid_t dxpl_id, hid_t estack_id)
{
- void *ret_value = NULL; /* Return value */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
+ void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
/* check if the type specific corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->datatype_cls.open)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "no datatype open callback");
-#if 0
- H5VL_loc_params_t loc_params;
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.plist_id = tapl_id;
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
- /* Open the object class */
- if((ret_value = H5VL_object_open(id, loc_params, dxpl_id, estack_id)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to open object")
-#endif
/* call the corresponding VOL open callback */
- if(NULL == (ret_value = (vol_plugin->cls->datatype_cls.open)(obj, loc_params, name, tapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->datatype_cls.open)(obj, loc_params, name, tapl_id,
+ dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
vol_plugin->nrefs ++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_datatype_open() */
@@ -853,8 +1005,10 @@ done:
*/
ssize_t
H5VL_datatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size_t size,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
ssize_t ret_value = FAIL;
FUNC_ENTER_NOAPI(FAIL)
@@ -862,10 +1016,27 @@ H5VL_datatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size
/* check if the type specific corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->datatype_cls.get_binary)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "no datatype get_binary callback");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* call the corresponding VOL open callback */
- if((ret_value = (vol_plugin->cls->datatype_cls.get_binary)(obj, buf, size, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->datatype_cls.get_binary)(obj, buf, size, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "get binary failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_datatype_get_binary() */
@@ -921,8 +1092,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -931,8 +1104,19 @@ H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED es
if(NULL == vol_plugin->cls->datatype_cls.close)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `datatype close' method")
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* call the corresponding VOL close callback */
- if((ret_value = (vol_plugin->cls->datatype_cls.close)(dt, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->datatype_cls.close)(dt, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
vol_plugin->nrefs --;
@@ -941,6 +1125,11 @@ H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED es
vol_plugin = (H5VL_t *)H5MM_xfree(vol_plugin);
}
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_datatype_close() */
@@ -962,20 +1151,39 @@ done:
*/
void *
H5VL_dataset_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL create callback exists */
if(NULL == vol_plugin->cls->dataset_cls.create)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `dataset create' method")
/* call the corresponding VOL create callback */
- if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.create)(obj, loc_params, name, dcpl_id, dapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.create)(obj, loc_params, name, dcpl_id,
+ dapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed")
vol_plugin->nrefs ++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_dataset_create() */
@@ -997,12 +1205,25 @@ done:
*/
void *
H5VL_dataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t dapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the type specific corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->dataset_cls.open) {
;
@@ -1014,11 +1235,18 @@ H5VL_dataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, c
}
else {
/* call the corresponding VOL open callback */
- if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.open)(obj, loc_params, name, dapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.open)(obj, loc_params, name,
+ dapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
vol_plugin->nrefs ++;
}
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_dataset_open() */
@@ -1040,18 +1268,36 @@ done:
*/
herr_t
H5VL_dataset_read(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id,
- hid_t file_space_id, hid_t plist_id, void *buf, hid_t UNUSED estack_id)
+ hid_t file_space_id, hid_t plist_id, void *buf, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->dataset_cls.read)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset read' method")
if((ret_value = (vol_plugin->cls->dataset_cls.read)
- (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, H5_REQUEST_NULL)) < 0)
+ (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "read failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_dataset_read() */
@@ -1073,18 +1319,36 @@ done:
*/
herr_t
H5VL_dataset_write(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id,
- hid_t file_space_id, hid_t plist_id, const void *buf, hid_t UNUSED estack_id)
+ hid_t file_space_id, hid_t plist_id, const void *buf, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->dataset_cls.write)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset write' method")
if((ret_value = (vol_plugin->cls->dataset_cls.write)
- (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, H5_REQUEST_NULL)) < 0)
+ (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "write failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_dataset_write() */
@@ -1106,17 +1370,35 @@ done:
*/
herr_t
H5VL_dataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[],
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->dataset_cls.set_extent)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset set_extent' method")
- if((ret_value = (vol_plugin->cls->dataset_cls.set_extent)(dset, size, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->dataset_cls.set_extent)(dset, size, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "set_extent failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_dataset_set_extent() */
@@ -1149,7 +1431,8 @@ H5VL_dataset_get(void *dset, H5VL_t *vol_plugin, H5VL_dataset_get_t get_type,
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset get' method")
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->cls->dataset_cls.get)(dset, get_type, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->cls->dataset_cls.get)(dset, get_type, dxpl_id,
+ H5_REQUEST_NULL, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed")
va_end (arguments);
@@ -1190,24 +1473,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
- /* if the VOL class does not implement a specific dataset close
- callback, try the object close */
- if(NULL == vol_plugin->cls->dataset_cls.close){
- ;
-#if 0
- if(H5VL_object_close(id, dxpl_id, dxpl_id, estack_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object")
-#endif
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
}
- else {
- if((ret_value = (vol_plugin->cls->dataset_cls.close)(dset, dxpl_id, H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
+ if((ret_value = (vol_plugin->cls->dataset_cls.close)(dset, dxpl_id, req)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
}
vol_plugin->nrefs --;
@@ -1236,38 +1525,56 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5VL_file_create(H5VL_t **plugin, const char *name, unsigned flags, hid_t fcpl_id,
- hid_t fapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_file_create(H5VL_t **plugin, const char *filename, unsigned flags, hid_t fcpl_id,
+ hid_t fapl_id, hid_t dxpl_id, hid_t estack_id)
{
H5P_genplist_t *plist; /* Property list pointer */
H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */
H5VL_t *vol_plugin = NULL; /* the public VOL struct */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
/* get the VOL info from the fapl */
if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list");
if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID")
-
- /* check if the corresponding VOL create callback exists */
- if(NULL == vol_cls->file_cls.create)
- HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file create' method")
- /* call the corresponding VOL create callback */
- if(NULL == (ret_value = (vol_cls->file_cls.create)(name, flags, fcpl_id, fapl_id, dxpl_id, H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID");
/* Build the vol plugin struct */
if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
vol_plugin = *plugin;
vol_plugin->cls = vol_cls;
vol_plugin->nrefs = 1;
- if((vol_plugin->container_name = H5MM_xstrdup(name)) == NULL)
- HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed")
+ if((vol_plugin->container_name = H5MM_xstrdup(filename)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed");
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* check if the corresponding VOL create callback exists */
+ if(NULL == vol_cls->file_cls.create)
+ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file create' method")
+ /* call the corresponding VOL create callback */
+ if(NULL == (ret_value = (vol_cls->file_cls.create)(filename, flags, fcpl_id, fapl_id,
+ dxpl_id, req)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed");
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1289,12 +1596,14 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5VL_file_open(H5VL_t **plugin, const char *name, unsigned flags, hid_t fapl_id,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_file_open(H5VL_t **plugin, const char *filename, unsigned flags, hid_t fapl_id,
+ hid_t dxpl_id, hid_t estack_id)
{
H5P_genplist_t *plist; /* Property list pointer */
H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */
H5VL_t *vol_plugin = NULL; /* the public VOL struct */
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1305,23 +1614,39 @@ H5VL_file_open(H5VL_t **plugin, const char *name, unsigned flags, hid_t fapl_id,
if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID")
- /* check if the corresponding VOL create callback exists */
- if(NULL == vol_cls->file_cls.open)
- HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method")
- /* call the corresponding VOL create callback */
- if(NULL == (ret_value = (vol_cls->file_cls.open)(name, flags, fapl_id, dxpl_id, H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
-
/* Build the vol plugin struct */
if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
vol_plugin = *plugin;
vol_plugin->cls = vol_cls;
vol_plugin->nrefs = 1;
- if((vol_plugin->container_name = H5MM_xstrdup(name)) == NULL)
+ if((vol_plugin->container_name = H5MM_xstrdup(filename)) == NULL)
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed")
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ /* check if the corresponding VOL create callback exists */
+ if(NULL == vol_cls->file_cls.open)
+ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method")
+ /* call the corresponding VOL create callback */
+ if(NULL == (ret_value = (vol_cls->file_cls.open)(filename, flags, fapl_id,
+ dxpl_id, req)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_file_open() */
@@ -1343,17 +1668,36 @@ done:
*/
herr_t
H5VL_file_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5F_scope_t scope,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->file_cls.flush)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file flush' method")
- if((ret_value = (vol_plugin->cls->file_cls.flush)(obj, loc_params, scope, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->file_cls.flush)(obj, loc_params, scope,
+ dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTFLUSH, FAIL, "flush failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_file_flush() */
@@ -1508,17 +1852,35 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_file_close(void *file, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_file_close(void *file, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
if(NULL == vol_plugin->cls->file_cls.close)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file close' method")
- if((ret_value = (vol_plugin->cls->file_cls.close)(file, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->file_cls.close)(file, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "close failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
vol_plugin->nrefs --;
if (0 == vol_plugin->nrefs) {
vol_plugin->container_name = (const char *)H5MM_xfree(vol_plugin->container_name);
@@ -1546,20 +1908,39 @@ done:
*/
void *
H5VL_group_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL create callback exists */
if(NULL == vol_plugin->cls->group_cls.create)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `group create' method")
/* call the corresponding VOL create callback */
- if(NULL == (ret_value = (vol_plugin->cls->group_cls.create)(obj, loc_params, name, gcpl_id, gapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->group_cls.create)(obj, loc_params, name, gcpl_id,
+ gapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed")
vol_plugin->nrefs ++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_group_create() */
@@ -1581,12 +1962,25 @@ done:
*/
void *
H5VL_group_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name,
- hid_t gapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t gapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the type specific corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->group_cls.open) {
;
@@ -1598,10 +1992,17 @@ H5VL_group_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, con
}
else {
/* call the corresponding VOL open callback */
- if(NULL == (ret_value = (vol_plugin->cls->group_cls.open)(obj, loc_params, name, gapl_id, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->group_cls.open)(obj, loc_params, name,
+ gapl_id, dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
vol_plugin->nrefs ++;
}
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_group_open() */
@@ -1657,25 +2058,32 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI_NOINIT
- /* if the VOL class does not implement a specific group close
- callback, try the object close */
- if(NULL == vol_plugin->cls->group_cls.close) {
- ;
-#if 0
- if(H5VL_object_close(id, dxpl_id, estack_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object")
-#endif
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
+ if((ret_value = (vol_plugin->cls->group_cls.close)(grp, dxpl_id, req)) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
}
- else {
- if((ret_value = (vol_plugin->cls->group_cls.close)(grp, dxpl_id, H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
- }
vol_plugin->nrefs --;
if (0 == vol_plugin->nrefs) {
@@ -1702,20 +2110,38 @@ done:
*/
herr_t
H5VL_link_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params,
- H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL create callback exists */
if(NULL == vol_plugin->cls->link_cls.create)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link create' method")
/* call the corresponding VOL create callback */
if((ret_value = (vol_plugin->cls->link_cls.create)
- (create_type, obj, loc_params, lcpl_id, lapl_id, dxpl_id, H5_REQUEST_NULL)) < 0)
+ (create_type, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link create failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_link_create() */
@@ -1736,20 +2162,38 @@ done:
herr_t
H5VL_link_move(void *src_obj, H5VL_loc_params_t loc_params1, void *dst_obj,
H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin, hbool_t copy_flag,
- hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL move callback exists */
if(NULL == vol_plugin->cls->link_cls.move)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link move' method")
/* call the corresponding VOL move callback */
if((ret_value = (vol_plugin->cls->link_cls.move)
- (src_obj, loc_params1, dst_obj, loc_params2, copy_flag, lcpl_id, lapl_id, dxpl_id, H5_REQUEST_NULL)) < 0)
+ (src_obj, loc_params1, dst_obj, loc_params2, copy_flag, lcpl_id, lapl_id, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link move failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_link_move() */
@@ -1771,18 +2215,36 @@ done:
herr_t
H5VL_link_iterate(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin,
hbool_t recursive, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
- H5L_iterate_t op, void *op_data, hid_t dxpl_id, hid_t UNUSED estack_id)
+ H5L_iterate_t op, void *op_data, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->link_cls.iterate)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link iterate' method")
if((ret_value = (vol_plugin->cls->link_cls.iterate)(obj, loc_params, recursive, idx_type,
- order, idx, op, op_data, dxpl_id, H5_REQUEST_NULL)) < 0)
+ order, idx, op, op_data, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "iteration failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_link_iterate() */
@@ -1806,18 +2268,36 @@ herr_t
H5VL_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_link_get_t get_type,
hid_t dxpl_id, hid_t estack_id, ...)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
va_list arguments; /* argument list passed from the API call */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->link_cls.get)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link get' method")
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->cls->link_cls.get)(obj, loc_params, get_type, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->cls->link_cls.get)(obj, loc_params, get_type, dxpl_id, req, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed")
va_end (arguments);
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_link_get() */
@@ -1837,19 +2317,37 @@ done:
*/
herr_t
H5VL_link_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL remove callback exists */
if(NULL == vol_plugin->cls->link_cls.remove)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link remove' method")
/* call the corresponding VOL remove callback */
- if((ret_value = (vol_plugin->cls->link_cls.remove)(obj, loc_params, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->link_cls.remove)(obj, loc_params, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link remove failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_link_remove() */
@@ -1871,20 +2369,39 @@ done:
*/
void *
H5VL_object_open(void *obj, H5VL_loc_params_t params, H5VL_t *vol_plugin, H5I_type_t *opened_type,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
/* check if the corresponding VOL open callback exists */
if(NULL == vol_plugin->cls->object_cls.open)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `object open' method")
/* call the corresponding VOL open callback */
- if(NULL == (ret_value = (vol_plugin->cls->object_cls.open)(obj, params, opened_type, dxpl_id, H5_REQUEST_NULL)))
+ if(NULL == (ret_value = (vol_plugin->cls->object_cls.open)(obj, params, opened_type,
+ dxpl_id, req)))
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed")
vol_plugin->nrefs++;
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_open() */
@@ -1906,22 +2423,41 @@ done:
herr_t
H5VL_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, H5VL_t *vol_plugin1, const char *src_name,
void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin2, const char *dst_name,
- hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin1;
+ }
+
/* check if both objects are associated with the same VOL plugin */
if(vol_plugin1->cls != vol_plugin2->cls)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be copied")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
+ "Objects are accessed through different VOL plugins and can't be copied")
if(NULL == vol_plugin1->cls->object_cls.copy)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object copy' method")
if((ret_value = (vol_plugin1->cls->object_cls.copy)
- (src_obj, loc_params1, src_name, dst_obj, loc_params2, dst_name, ocpypl_id, lcpl_id, dxpl_id, H5_REQUEST_NULL)) < 0)
+ (src_obj, loc_params1, src_name, dst_obj, loc_params2, dst_name,
+ ocpypl_id, lcpl_id, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "copy failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_copy() */
@@ -1942,19 +2478,37 @@ done:
*/
herr_t H5VL_object_visit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin,
H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op,
- void *op_data, hid_t dxpl_id, hid_t UNUSED estack_id)
+ void *op_data, hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->object_cls.visit)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object visit' method")
if((ret_value = (vol_plugin->cls->object_cls.visit)(obj, loc_params, idx_type, order, op,
- op_data, dxpl_id, H5_REQUEST_NULL)) < 0)
+ op_data, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "object visitation failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_visit() */
@@ -1992,7 +2546,7 @@ H5VL_object_lookup(hid_t id, H5VL_loc_type_t lookup_type, void **location,
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object lookup' method")
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->object_cls.lookup)(id, lookup_type, location, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->object_cls.lookup)(id, lookup_type, location, dxpl_id, req, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "lookup of object location failed")
va_end (arguments);
done:
@@ -2014,7 +2568,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_object_free_loc(hid_t id, void *location, hid_t dxpl_id, hid_t UNUSED estack_id)
+H5VL_object_free_loc(hid_t id, void *location, hid_t dxpl_id, hid_t estack_id)
{
H5VL_class_t *vol_plugin; /* VOL structure attached to id */
herr_t ret_value = SUCCEED;
@@ -2027,7 +2581,7 @@ H5VL_object_free_loc(hid_t id, void *location, hid_t dxpl_id, hid_t UNUSED estac
if(NULL == vol_plugin->object_cls.free_loc)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object free_loc' method")
- if((ret_value = (vol_plugin->object_cls.free_loc)(location, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->object_cls.free_loc)(location, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "freeing location token of object location failed")
done:
@@ -2054,18 +2608,38 @@ herr_t
H5VL_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_get_t get_type,
hid_t dxpl_id, hid_t estack_id, ...)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
va_list arguments; /* argument list passed from the API call */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->object_cls.get)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object get' method")
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->cls->object_cls.get)(obj, loc_params, get_type, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->cls->object_cls.get)(obj, loc_params, get_type,
+ dxpl_id, req, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed")
va_end (arguments);
+
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_get() */
@@ -2088,19 +2662,38 @@ herr_t
H5VL_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t misc_type,
hid_t dxpl_id, hid_t estack_id, ...)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
va_list arguments; /* argument list passed from the API call */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->object_cls.misc)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object misc' method")
va_start (arguments, estack_id);
- if((ret_value = (vol_plugin->cls->object_cls.misc)(obj, loc_params, misc_type, dxpl_id, H5_REQUEST_NULL, arguments)) < 0)
+ if((ret_value = (vol_plugin->cls->object_cls.misc)(obj, loc_params, misc_type,
+ dxpl_id, req, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "misc failed")
va_end (arguments);
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_misc() */
@@ -2122,17 +2715,35 @@ done:
*/
herr_t
H5VL_object_close(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin,
- hid_t dxpl_id, hid_t UNUSED estack_id)
+ hid_t dxpl_id, hid_t estack_id)
{
+ H5_priv_request_t *request = NULL; /* private request struct inserted in event stack */
+ void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
+ if(estack_id != H5_EVENT_STACK_NULL) {
+ /* create the private request */
+ if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ request->req = NULL;
+ req = &request->req;
+ request->next = NULL;
+ request->vol_plugin = vol_plugin;
+ vol_plugin->nrefs ++;
+ }
+
if(NULL == vol_plugin->cls->object_cls.close)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object close' method")
- if((ret_value = (vol_plugin->cls->object_cls.close)(obj, loc_params, dxpl_id, H5_REQUEST_NULL)) < 0)
+ if((ret_value = (vol_plugin->cls->object_cls.close)(obj, loc_params, dxpl_id, req)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed")
+ if(request && *req) {
+ if(H5ES_insert(estack_id, request) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event stack");
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_object_close() */
diff --git a/src/H5VLiod.c b/src/H5VLiod.c
new file mode 100644
index 0000000..7308184
--- /dev/null
+++ b/src/H5VLiod.c
@@ -0,0 +1,9251 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * February, 2012
+ *
+ * Purpose: The IOD VOL plugin where access is forwarded to the IOD library
+ * by the function shipper.
+ */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5VL_iod_init_interface
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FDprivate.h" /* file drivers */
+#include "H5FFprivate.h" /* Fast Forward */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspaces */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod.h" /* Iod VOL plugin */
+#include "H5VLiod_client.h" /* Client IOD helper */
+
+#ifdef H5_HAVE_EFF
+
+#define H5VL_IOD_MAX_ADDR_NAME 256
+
+/* function shipper IDs for different routines */
+static hg_id_t H5VL_EFF_INIT_ID;
+static hg_id_t H5VL_EFF_FINALIZE_ID;
+static hg_id_t H5VL_ANALYSIS_EXECUTE_ID;
+static hg_id_t H5VL_FILE_CREATE_ID;
+static hg_id_t H5VL_FILE_OPEN_ID;
+static hg_id_t H5VL_FILE_CLOSE_ID;
+static hg_id_t H5VL_ATTR_CREATE_ID;
+static hg_id_t H5VL_ATTR_OPEN_ID;
+static hg_id_t H5VL_ATTR_READ_ID;
+static hg_id_t H5VL_ATTR_WRITE_ID;
+static hg_id_t H5VL_ATTR_EXISTS_ID;
+static hg_id_t H5VL_ATTR_ITERATE_ID;
+static hg_id_t H5VL_ATTR_RENAME_ID;
+static hg_id_t H5VL_ATTR_REMOVE_ID;
+static hg_id_t H5VL_ATTR_CLOSE_ID;
+static hg_id_t H5VL_GROUP_CREATE_ID;
+static hg_id_t H5VL_GROUP_OPEN_ID;
+static hg_id_t H5VL_GROUP_CLOSE_ID;
+static hg_id_t H5VL_MAP_CREATE_ID;
+static hg_id_t H5VL_MAP_OPEN_ID;
+static hg_id_t H5VL_MAP_SET_ID;
+static hg_id_t H5VL_MAP_GET_ID;
+static hg_id_t H5VL_MAP_GET_COUNT_ID;
+static hg_id_t H5VL_MAP_EXISTS_ID;
+static hg_id_t H5VL_MAP_ITERATE_ID;
+static hg_id_t H5VL_MAP_DELETE_ID;
+static hg_id_t H5VL_MAP_CLOSE_ID;
+static hg_id_t H5VL_DSET_CREATE_ID;
+static hg_id_t H5VL_DSET_OPEN_ID;
+static hg_id_t H5VL_DSET_READ_ID;
+static hg_id_t H5VL_DSET_GET_VL_SIZE_ID;
+static hg_id_t H5VL_DSET_WRITE_ID;
+static hg_id_t H5VL_DSET_SET_EXTENT_ID;
+static hg_id_t H5VL_DSET_CLOSE_ID;
+static hg_id_t H5VL_DTYPE_COMMIT_ID;
+static hg_id_t H5VL_DTYPE_OPEN_ID;
+static hg_id_t H5VL_DTYPE_CLOSE_ID;
+static hg_id_t H5VL_LINK_CREATE_ID;
+static hg_id_t H5VL_LINK_MOVE_ID;
+static hg_id_t H5VL_LINK_ITERATE_ID;
+static hg_id_t H5VL_LINK_EXISTS_ID;
+static hg_id_t H5VL_LINK_GET_INFO_ID;
+static hg_id_t H5VL_LINK_GET_VAL_ID;
+static hg_id_t H5VL_LINK_REMOVE_ID;
+static hg_id_t H5VL_OBJECT_OPEN_BY_TOKEN_ID;
+static hg_id_t H5VL_OBJECT_OPEN_ID;
+static hg_id_t H5VL_OBJECT_COPY_ID;
+static hg_id_t H5VL_OBJECT_EXISTS_ID;
+static hg_id_t H5VL_OBJECT_VISIT_ID;
+static hg_id_t H5VL_OBJECT_SET_COMMENT_ID;
+static hg_id_t H5VL_OBJECT_GET_COMMENT_ID;
+static hg_id_t H5VL_OBJECT_GET_INFO_ID;
+static hg_id_t H5VL_RC_ACQUIRE_ID;
+static hg_id_t H5VL_RC_RELEASE_ID;
+static hg_id_t H5VL_RC_PERSIST_ID;
+static hg_id_t H5VL_RC_SNAPSHOT_ID;
+static hg_id_t H5VL_TR_START_ID;
+static hg_id_t H5VL_TR_FINISH_ID;
+static hg_id_t H5VL_TR_SET_DEPEND_ID;
+static hg_id_t H5VL_TR_SKIP_ID;
+static hg_id_t H5VL_TR_ABORT_ID;
+static hg_id_t H5VL_PREFETCH_ID;
+static hg_id_t H5VL_EVICT_ID;
+static hg_id_t H5VL_CANCEL_OP_ID;
+
+
+/* global AXE list struct */
+typedef struct H5VL_iod_axe_list_t {
+ H5VL_iod_request_t *head;
+ H5VL_iod_request_t *tail;
+ AXE_task_t last_released_task;
+} H5VL_iod_axe_list_t;
+
+static na_addr_t PEER;
+static na_class_t *network_class = NULL;
+
+static AXE_task_t g_axe_id;
+static H5VL_iod_axe_list_t axe_list;
+
+/* Prototypes */
+static void *H5VL_iod_fapl_copy(const void *_old_fa);
+static herr_t H5VL_iod_fapl_free(void *_fa);
+
+/* Atrribute callbacks */
+static void *H5VL_iod_attribute_create(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_iod_attribute_open(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t aapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_attribute_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_attribute_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_attribute_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_attribute_remove(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_attribute_close(void *attr, hid_t dxpl_id, void **req);
+
+/* Datatype callbacks */
+static void *H5VL_iod_datatype_commit(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_iod_datatype_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req);
+static ssize_t H5VL_iod_datatype_get_binary(void *obj, unsigned char *buf, size_t size, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_datatype_get(void *obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_datatype_close(void *dt, hid_t dxpl_id, void **req);
+
+/* Dataset callbacks */
+static void *H5VL_iod_dataset_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_iod_dataset_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, void *buf, void **req);
+static herr_t H5VL_iod_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
+static herr_t H5VL_iod_dataset_set_extent(void *dset, const hsize_t size[], hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_dataset_close(void *dset, hid_t dxpl_id, void **req);
+
+/* File callbacks */
+static void *H5VL_iod_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_iod_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_file_close(void *file, hid_t dxpl_id, void **req);
+
+/* Group callbacks */
+static void *H5VL_iod_group_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_iod_group_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_group_close(void *grp, hid_t dxpl_id, void **req);
+
+/* Link callbacks */
+static herr_t H5VL_iod_link_create(H5VL_link_create_type_t create_type, void *obj,
+ H5VL_loc_params_t loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_link_move(void *src_obj, H5VL_loc_params_t loc_params1,
+ void *dst_obj, H5VL_loc_params_t loc_params2,
+ hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_link_iterate(void *obj, H5VL_loc_params_t loc_params, hbool_t recursive,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
+ H5L_iterate_t op, void *op_data, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_link_remove(void *obj, H5VL_loc_params_t loc_params, hid_t dxpl_id, void **req);
+
+/* Object callbacks */
+static void *H5VL_iod_object_open(void *obj, H5VL_loc_params_t loc_params, H5I_type_t *opened_type, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, const char *src_name,
+ void *dst_obj, H5VL_loc_params_t loc_params2, const char *dst_name,
+ hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_object_visit(void *obj, H5VL_loc_params_t loc_params, H5_index_t idx_type,
+ H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t dxpl_id, void **req);
+static herr_t H5VL_iod_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_iod_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_object_misc_t misc_type, hid_t dxpl_id, void **req, va_list arguments);
+
+static herr_t H5VL_iod_cancel(void **req, H5ES_status_t *status);
+static herr_t H5VL_iod_test(void **req, H5ES_status_t *status);
+static herr_t H5VL_iod_wait(void **req, H5ES_status_t *status);
+
+/* IOD-specific file access properties */
+typedef struct H5VL_iod_fapl_t {
+ MPI_Comm comm; /*communicator */
+ MPI_Info info; /*file information */
+} H5VL_iod_fapl_t;
+
+H5FL_DEFINE(H5VL_iod_file_t);
+H5FL_DEFINE(H5VL_iod_attr_t);
+H5FL_DEFINE(H5VL_iod_group_t);
+H5FL_DEFINE(H5VL_iod_map_t);
+H5FL_DEFINE(H5VL_iod_dset_t);
+H5FL_DEFINE(H5VL_iod_dtype_t);
+
+static H5VL_class_t H5VL_iod_g = {
+ IOD,
+ "iod", /* name */
+ NULL, /* initialize */
+ NULL, /* terminate */
+ sizeof(H5VL_iod_fapl_t), /*fapl_size */
+ H5VL_iod_fapl_copy, /*fapl_copy */
+ H5VL_iod_fapl_free, /*fapl_free */
+ { /* attribute_cls */
+ H5VL_iod_attribute_create, /* create */
+ H5VL_iod_attribute_open, /* open */
+ H5VL_iod_attribute_read, /* read */
+ H5VL_iod_attribute_write, /* write */
+ NULL,//H5VL_iod_attr_iterate, /* iterate */
+ H5VL_iod_attribute_get, /* get */
+ H5VL_iod_attribute_remove, /* remove */
+ H5VL_iod_attribute_close /* close */
+ },
+ { /* datatype_cls */
+ H5VL_iod_datatype_commit, /* commit */
+ H5VL_iod_datatype_open, /* open */
+ H5VL_iod_datatype_get_binary, /* get_size */
+ H5VL_iod_datatype_get, /* get */
+ H5VL_iod_datatype_close /* close */
+ },
+ { /* dataset_cls */
+ H5VL_iod_dataset_create, /* create */
+ H5VL_iod_dataset_open, /* open */
+ H5VL_iod_dataset_read, /* read */
+ H5VL_iod_dataset_write, /* write */
+ H5VL_iod_dataset_set_extent, /* set extent */
+ H5VL_iod_dataset_get, /* get */
+ H5VL_iod_dataset_close /* close */
+ },
+ { /* file_cls */
+ H5VL_iod_file_create, /* create */
+ H5VL_iod_file_open, /* open */
+ NULL, /* flush */
+ H5VL_iod_file_get, /* get */
+ NULL, /* misc */
+ NULL, /* optional */
+ H5VL_iod_file_close /* close */
+ },
+ { /* group_cls */
+ H5VL_iod_group_create, /* create */
+ H5VL_iod_group_open, /* open */
+ H5VL_iod_group_get, /* get */
+ H5VL_iod_group_close /* close */
+ },
+ { /* link_cls */
+ H5VL_iod_link_create, /* create */
+ H5VL_iod_link_move, /* move */
+ H5VL_iod_link_iterate, /* iterate */
+ H5VL_iod_link_get, /* get */
+ H5VL_iod_link_remove /* remove */
+ },
+ { /* object_cls */
+ H5VL_iod_object_open, /* open */
+ H5VL_iod_object_copy, /* copy */
+ H5VL_iod_object_visit, /* visit */
+ H5VL_iod_object_get, /* get */
+ H5VL_iod_object_misc, /* misc */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ H5VL_iod_cancel,
+ H5VL_iod_test,
+ H5VL_iod_wait
+ }
+};
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5VL_iod_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5VL_iod_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5VL_iod_init currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5VL_iod_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5VL_iod_init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_init
+ *
+ * Purpose: Initialize this vol plugin by registering the driver with the
+ * library.
+ *
+ * Return: Success: The ID for the iod plugin.
+ * Failure: Negative.
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+H5VL_class_t *
+H5VL_iod_init(void)
+{
+ H5VL_class_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Set return value */
+ ret_value = &H5VL_iod_g;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_request_remove_from_axe_list
+ *
+ * Purpose: Utility routine to remove a node from the global list of
+ * AXE tasks.
+ *
+ * Return: Success: Positive
+ * Failure: Negative.
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_request_remove_from_axe_list(H5VL_iod_request_t *request)
+{
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(request);
+
+ prev = request->global_prev;
+ next = request->global_next;
+
+ if (prev) {
+ if (next) {
+ prev->global_next = next;
+ next->global_prev = prev;
+ }
+ else {
+ prev->global_next = NULL;
+ axe_list.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->global_prev = NULL;
+ axe_list.head = next;
+ }
+ else {
+ axe_list.head = NULL;
+ axe_list.tail = NULL;
+ }
+ }
+
+ request->global_prev = NULL;
+ request->global_next = NULL;
+
+ H5VL_iod_request_decr_rc(request);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL__iod_request_remove_from_axe_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_request_add_to_axe_list
+ *
+ * Purpose: Utility routine to add a node to the global list of AXE
+ * tasks. This routine also checks which tasks have completed
+ * and can be freed by the VOL callback that is calling this
+ * routine, and updates the last_released_task global variable
+ * accordingly.
+ *
+ * Return: Success: Positive
+ * Failure: Negative.
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_request_add_to_axe_list(H5VL_iod_request_t *request)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(request);
+
+ if (axe_list.tail) {
+ axe_list.tail->global_next = request;
+ request->global_prev = axe_list.tail;
+ axe_list.tail = request;
+ }
+ else {
+ axe_list.head = request;
+ axe_list.tail = request;
+ request->global_prev = NULL;
+ }
+
+ request->global_next = NULL;
+ request->ref_count ++;
+
+ /* process axe_list */
+ while(axe_list.head && /* If there is a head request */
+ /* and the only reference is from this global axe list OR
+ from the axe list and the file list */
+ (axe_list.head->ref_count == 1 || (axe_list.head->ref_count == 2 && request->req != NULL)) &&
+ /* and the request has completed */
+ H5VL_IOD_COMPLETED == axe_list.head->state) {
+
+ /* add the axe IDs to the ones to free. */
+ axe_list.last_released_task = axe_list.head->axe_id;
+
+ /* remove head from axe list */
+ H5VL__iod_request_remove_from_axe_list(axe_list.head);
+ }
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+}/* end H5VL__iod_request_add_to_axe_list() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_create_and_forward
+ *
+ * Purpose: Utility routine to create a mercury request and a
+ * VOL IOD request and ship the op to the server.
+ *
+ * Return: Success: Positive
+ * Failure: Negative.
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__iod_create_and_forward(hg_id_t op_id, H5RQ_type_t op_type,
+ H5VL_iod_object_t *request_obj, htri_t track,
+ size_t num_parents, H5VL_iod_request_t **parent_reqs,
+ H5VL_iod_req_info_t *req_info,
+ void *input, void *output, void *data, void **req)
+{
+ hg_request_t *hg_req = NULL;
+ H5VL_iod_request_t *request = NULL;
+ hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */
+ axe_t *axe_info = (axe_t *) input;
+ AXE_task_t *parent_axe_ids = NULL;
+ unsigned u;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get a function shipper request */
+ if(NULL == (hg_req = (hg_request_t *)H5MM_malloc(sizeof(hg_request_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate a HG request");
+
+ /* Get async request for operation */
+ if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct");
+
+ /* get axe ID for operation */
+ axe_info->axe_id = g_axe_id ++;
+
+ /* Set up request */
+ HDmemset(request, 0, sizeof(*request));
+ request->type = op_type;
+ request->data = data;
+ request->req = hg_req;
+ request->ref_count = 1;
+ request->obj = request_obj;
+ request->axe_id = axe_info->axe_id;
+ request->file_next = request->file_prev = NULL;
+ request->global_next = request->global_prev = NULL;
+
+ if(do_async)
+ request->trans_info = req_info;
+
+ /* add request to container's linked list */
+ if(HG_ANALYSIS_EXECUTE != op_type)
+ H5VL_iod_request_add(request_obj->file, request);
+
+ /* update the parent information in the request */
+ request->num_parents = num_parents;
+ request->parent_reqs = parent_reqs;
+
+ if(num_parents) {
+ if(NULL == (parent_axe_ids = (AXE_task_t *)H5MM_malloc(sizeof(AXE_task_t) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent axe IDs");
+
+ for(u=0 ; u<num_parents ; u++)
+ parent_axe_ids[u] = parent_reqs[u]->axe_id;
+ }
+
+ axe_info->num_parents = num_parents;
+ axe_info->parent_axe_ids = parent_axe_ids;
+
+ axe_info->start_range = axe_list.last_released_task + 1;
+ /* add request to global axe's linked list */
+ H5VL__iod_request_add_to_axe_list(request);
+ axe_info->count = axe_list.last_released_task - axe_info->start_range + 1;
+
+#if H5VL_IOD_DEBUG
+ printf("Operation %"PRIu64" Dependencies: ", request->axe_id);
+ for(u=0 ; u<num_parents ; u++)
+ printf("%"PRIu64" ", axe_info->parent_axe_ids[u]);
+ printf("\n");
+
+ if(axe_info->count) {
+ printf("Operation %"PRIu64" will finish tasks %"PRIu64" through %"PRIu64"\n",
+ request->axe_id, axe_info->start_range,
+ axe_info->start_range+axe_info->count-1);
+ }
+#endif
+
+ /* forward the call to the ION */
+ if(HG_Forward(PEER, op_id, input, output, hg_req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+
+ /* Store/wait on request */
+ if(do_async) {
+ *req = request;
+
+ /* Track request */
+ if(track)
+ request_obj->request = request;
+ } /* end if */
+ else {
+ if(track)
+ request_obj->request = NULL;
+
+ if(HG_ANALYSIS_EXECUTE == op_type) {
+ int ret;
+ hg_status_t status;
+
+ /* test the operation status */
+ ret = HG_Wait(*((hg_request_t *)request->req), HG_MAX_IDLE_TIME, &status);
+ if(HG_FAIL == ret) {
+ fprintf(stderr, "failed to wait on request\n");
+ request->status = H5ES_STATUS_FAIL;
+ request->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ if(status) {
+ request->status = H5ES_STATUS_SUCCEED;
+ request->state = H5VL_IOD_COMPLETED;
+ }
+ }
+ }
+ else {
+ /* Synchronously wait on the request */
+ if(H5VL_iod_request_wait(request_obj->file, request) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on HG request");
+ }
+
+ /* Since the operation is synchronous, return FAIL if the status failed */
+ if(H5ES_STATUS_FAIL == request->status) {
+ ret_value = FAIL;
+ }
+
+ request->req = H5MM_xfree(request->req);
+ H5VL_iod_request_decr_rc(request);
+ } /* end else */
+
+done:
+ parent_axe_ids = (AXE_task_t *)H5MM_xfree(parent_axe_ids);
+ FUNC_LEAVE_NOAPI(ret_value)
+}/* end H5VL__iod_create_and_forward() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: EFF_init
+ *
+ * Purpose: initialize to the EFF stack
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+EFF_init(MPI_Comm comm, MPI_Info UNUSED info)
+{
+ //char mpi_port_name[MPI_MAX_PORT_NAME];
+ int tag = 123456;
+ hg_request_t hg_req;
+ int num_procs, my_rank;
+ na_addr_t ion_target;
+ double axe_seed;
+ char addr_name[H5VL_IOD_MAX_ADDR_NAME];
+ herr_t ret_value = SUCCEED;
+
+ MPI_Comm_size(comm, &num_procs);
+ MPI_Comm_rank(comm, &my_rank);
+
+ /* generate global variables to create and track axe_ids for every
+ operation. Each process owns a portion of the ID space and uses
+ that space incrementally. */
+ axe_seed = (pow(2.0,64.0) - 1) / num_procs;
+ g_axe_id = (AXE_task_t)(axe_seed * my_rank + 1);
+
+ axe_list.last_released_task = g_axe_id - 1;
+ axe_list.head = NULL;
+ axe_list.tail = NULL;
+
+ /* MSC - This is a temporary solution for connecting to the server
+ using mercury */
+ /* Only rank 0 reads file */
+ if (my_rank == 0) {
+ int count, line=0, num_ions;
+ FILE *config;
+ char config_addr_name[H5VL_IOD_MAX_ADDR_NAME];
+
+ config = fopen("port.cfg", "r");
+
+ fscanf(config, "%d\n", &num_ions);
+
+#if H5VL_IOD_DEBUG
+ printf("Found %d servers\n", num_ions);
+#endif
+
+ /* read a line */
+ if(fgets(config_addr_name, H5VL_IOD_MAX_ADDR_NAME, config) != NULL) {
+ strncpy(addr_name, config_addr_name, H5VL_IOD_MAX_ADDR_NAME);
+ count = 1;
+ while(num_procs > line + (count*num_ions)) {
+ MPI_Send(config_addr_name, H5VL_IOD_MAX_ADDR_NAME, MPI_BYTE,
+ line + (count*num_ions), tag, comm);
+ count ++;
+ }
+ line++;
+ }
+
+ while (fgets(config_addr_name, H5VL_IOD_MAX_ADDR_NAME, config) != NULL) {
+ count = 0;
+ while(num_procs > line + (count*num_ions)) {
+ MPI_Send(config_addr_name, H5VL_IOD_MAX_ADDR_NAME, MPI_BYTE,
+ line + (count*num_ions), tag, comm);
+ count ++;
+ }
+ line ++;
+ }
+ fclose(config);
+ }
+ else {
+ MPI_Recv(addr_name, H5VL_IOD_MAX_ADDR_NAME, MPI_BYTE,
+ 0, tag, comm, MPI_STATUS_IGNORE);
+ }
+
+#if H5VL_IOD_DEBUG
+ printf("CN %d Connecting to ION %s\n", my_rank, addr_name);
+#endif
+
+ /* initialize Mercury stuff */
+ network_class = NA_MPI_Init(NULL, 0);
+
+ if (HG_SUCCESS != HG_Init(network_class)) {
+ fprintf(stderr, "Failed to initialize Mercury\n");
+ return FAIL;
+ }
+ if (NA_SUCCESS != NA_Addr_lookup_wait(network_class, addr_name, &ion_target)) {
+ fprintf(stderr, "Server lookup failed\n");
+ return FAIL;
+ }
+
+ PEER = ion_target;
+
+ /* Register function and encoding/decoding functions */
+ H5VL_EFF_INIT_ID = MERCURY_REGISTER("eff_init", eff_init_in_t, ret_t);
+ H5VL_EFF_FINALIZE_ID = MERCURY_REGISTER("eff_finalize", ret_t, ret_t);
+
+ H5VL_ANALYSIS_EXECUTE_ID = MERCURY_REGISTER("analysis_execute",
+ analysis_execute_in_t,
+ analysis_execute_out_t);
+
+ H5VL_FILE_CREATE_ID = MERCURY_REGISTER("file_create", file_create_in_t, file_create_out_t);
+ H5VL_FILE_OPEN_ID = MERCURY_REGISTER("file_open", file_open_in_t, file_open_out_t);
+ H5VL_FILE_CLOSE_ID = MERCURY_REGISTER("file_close", file_close_in_t, ret_t);
+
+ H5VL_ATTR_CREATE_ID = MERCURY_REGISTER("attr_create", attr_create_in_t, attr_create_out_t);
+ H5VL_ATTR_OPEN_ID = MERCURY_REGISTER("attr_open", attr_open_in_t, attr_open_out_t);
+ H5VL_ATTR_READ_ID = MERCURY_REGISTER("attr_read", attr_io_in_t, ret_t);
+ H5VL_ATTR_WRITE_ID = MERCURY_REGISTER("attr_write", attr_io_in_t, ret_t);
+ H5VL_ATTR_EXISTS_ID = MERCURY_REGISTER("attr_exists", attr_op_in_t, htri_t);
+ H5VL_ATTR_ITERATE_ID = MERCURY_REGISTER("attr_iterate", attr_op_in_t, ret_t);
+ H5VL_ATTR_RENAME_ID = MERCURY_REGISTER("attr_rename", attr_rename_in_t, ret_t);
+ H5VL_ATTR_REMOVE_ID = MERCURY_REGISTER("attr_remove", attr_op_in_t, ret_t);
+ H5VL_ATTR_CLOSE_ID = MERCURY_REGISTER("attr_close", attr_close_in_t, ret_t);
+
+ H5VL_GROUP_CREATE_ID = MERCURY_REGISTER("group_create", group_create_in_t, group_create_out_t);
+ H5VL_GROUP_OPEN_ID = MERCURY_REGISTER("group_open", group_open_in_t, group_open_out_t);
+ H5VL_GROUP_CLOSE_ID = MERCURY_REGISTER("group_close", group_close_in_t, ret_t);
+
+ H5VL_MAP_CREATE_ID = MERCURY_REGISTER("map_create", map_create_in_t, map_create_out_t);
+ H5VL_MAP_OPEN_ID = MERCURY_REGISTER("map_open", map_open_in_t, map_open_out_t);
+ H5VL_MAP_SET_ID = MERCURY_REGISTER("map_set", map_set_in_t, ret_t);
+ H5VL_MAP_GET_ID = MERCURY_REGISTER("map_get", map_get_in_t, map_get_out_t);
+ H5VL_MAP_GET_COUNT_ID = MERCURY_REGISTER("map_get_count", map_get_count_in_t, int64_t);
+ H5VL_MAP_ITERATE_ID = MERCURY_REGISTER("map_iterate", map_op_in_t, ret_t);
+ H5VL_MAP_EXISTS_ID = MERCURY_REGISTER("map_exists", map_op_in_t, hbool_t);
+ H5VL_MAP_DELETE_ID = MERCURY_REGISTER("map_delete", map_op_in_t, ret_t);
+ H5VL_MAP_CLOSE_ID = MERCURY_REGISTER("map_close", map_close_in_t, ret_t);
+
+ H5VL_DSET_CREATE_ID = MERCURY_REGISTER("dset_create", dset_create_in_t, dset_create_out_t);
+ H5VL_DSET_OPEN_ID = MERCURY_REGISTER("dset_open", dset_open_in_t, dset_open_out_t);
+ H5VL_DSET_READ_ID = MERCURY_REGISTER("dset_read", dset_io_in_t, dset_read_out_t);
+ H5VL_DSET_GET_VL_SIZE_ID = MERCURY_REGISTER("dset_get_vl_size", dset_io_in_t, dset_read_out_t);
+ H5VL_DSET_WRITE_ID = MERCURY_REGISTER("dset_write", dset_io_in_t, ret_t);
+ H5VL_DSET_SET_EXTENT_ID = MERCURY_REGISTER("dset_set_extent",
+ dset_set_extent_in_t, ret_t);
+ H5VL_DSET_CLOSE_ID = MERCURY_REGISTER("dset_close", dset_close_in_t, ret_t);
+
+ H5VL_DTYPE_COMMIT_ID = MERCURY_REGISTER("dtype_commit", dtype_commit_in_t, dtype_commit_out_t);
+ H5VL_DTYPE_OPEN_ID = MERCURY_REGISTER("dtype_open", dtype_open_in_t, dtype_open_out_t);
+ H5VL_DTYPE_CLOSE_ID = MERCURY_REGISTER("dtype_close", dtype_close_in_t, ret_t);
+
+ H5VL_LINK_CREATE_ID = MERCURY_REGISTER("link_create", link_create_in_t, ret_t);
+ H5VL_LINK_MOVE_ID = MERCURY_REGISTER("link_move", link_move_in_t, ret_t);
+ H5VL_LINK_EXISTS_ID = MERCURY_REGISTER("link_exists", link_op_in_t, htri_t);
+ H5VL_LINK_GET_INFO_ID = MERCURY_REGISTER("link_get_info", link_op_in_t, linfo_t);
+ H5VL_LINK_GET_VAL_ID = MERCURY_REGISTER("link_get_val", link_get_val_in_t,
+ link_get_val_out_t);
+ H5VL_LINK_ITERATE_ID = MERCURY_REGISTER("link_iterate", link_op_in_t, ret_t);
+ H5VL_LINK_REMOVE_ID = MERCURY_REGISTER("link_remove", link_op_in_t, ret_t);
+
+ H5VL_OBJECT_OPEN_BY_TOKEN_ID = MERCURY_REGISTER("object_open_by_token",
+ object_token_in_t, iod_handles_t);
+ H5VL_OBJECT_OPEN_ID = MERCURY_REGISTER("object_open", object_op_in_t, object_open_out_t);
+ H5VL_OBJECT_COPY_ID = MERCURY_REGISTER("object_copy", object_copy_in_t, ret_t);
+ H5VL_OBJECT_EXISTS_ID = MERCURY_REGISTER("object_exists", object_op_in_t, htri_t);
+ H5VL_OBJECT_VISIT_ID = MERCURY_REGISTER("object_visit", object_op_in_t, ret_t);
+ H5VL_OBJECT_SET_COMMENT_ID = MERCURY_REGISTER("set_comment", object_set_comment_in_t, ret_t);
+ H5VL_OBJECT_GET_COMMENT_ID = MERCURY_REGISTER("get_comment", object_get_comment_in_t,
+ object_get_comment_out_t);
+ H5VL_OBJECT_GET_INFO_ID = MERCURY_REGISTER("object_get_info", object_op_in_t, oinfo_t);
+
+ H5VL_RC_ACQUIRE_ID = MERCURY_REGISTER("read_context_acquire",
+ rc_acquire_in_t, rc_acquire_out_t);
+ H5VL_RC_RELEASE_ID = MERCURY_REGISTER("read_context_release", rc_release_in_t, ret_t);
+ H5VL_RC_PERSIST_ID = MERCURY_REGISTER("read_context_persist", rc_persist_in_t, ret_t);
+ H5VL_RC_SNAPSHOT_ID = MERCURY_REGISTER("read_context_snapshot", rc_snapshot_in_t, ret_t);
+
+ H5VL_TR_START_ID = MERCURY_REGISTER("transaction_start", tr_start_in_t, ret_t);
+ H5VL_TR_FINISH_ID = MERCURY_REGISTER("transaction_finish", tr_finish_in_t, ret_t);
+ H5VL_TR_SET_DEPEND_ID = MERCURY_REGISTER("transaction_set_depend",tr_set_depend_in_t, ret_t);
+ H5VL_TR_SKIP_ID = MERCURY_REGISTER("transaction_skip", tr_skip_in_t, ret_t);
+ H5VL_TR_ABORT_ID = MERCURY_REGISTER("transaction_abort",tr_abort_in_t, ret_t);
+
+ H5VL_PREFETCH_ID = MERCURY_REGISTER("prefetch", prefetch_in_t, hrpl_t);
+ H5VL_EVICT_ID = MERCURY_REGISTER("evict", evict_in_t, ret_t);
+
+ H5VL_CANCEL_OP_ID = MERCURY_REGISTER("cancel_op", uint64_t, uint8_t);
+
+ /* forward the init call to the ION and wait for its completion */
+ if(HG_SUCCESS != HG_Forward(PEER, H5VL_EFF_INIT_ID, &num_procs, &ret_value, &hg_req)) {
+ fprintf(stderr, "Failed to initialize Stack\n");
+ return FAIL;
+ }
+
+ /* Wait for it to compete */
+ HG_Wait(hg_req, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE);
+
+ /* Free Mercury request */
+ if(HG_Request_free(hg_req) != HG_SUCCESS)
+ return FAIL;
+
+ return ret_value;
+} /* end EFF_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: EFF_finalize
+ *
+ * Purpose: shutdown the EFF stack
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+EFF_finalize(void)
+{
+ hg_request_t hg_req;
+ herr_t ret_value = SUCCEED;
+
+ H5VL_iod_request_t *cur_req = axe_list.head;
+
+ /* process axe_list */
+ while(cur_req) {
+ H5VL_iod_request_t *next_req = NULL;
+
+ next_req = cur_req->global_next;
+
+ HDassert(H5VL_IOD_COMPLETED == cur_req->state);
+ HDassert(cur_req->ref_count == 1);
+
+ /* add the axe IDs to the ones to free. */
+ axe_list.last_released_task = cur_req->axe_id;
+
+ /* remove head from axe list */
+ H5VL__iod_request_remove_from_axe_list(cur_req);
+
+ cur_req = next_req;
+ }
+
+ /* forward the finalize call to the ION and wait for it to complete */
+ if(HG_Forward(PEER, H5VL_EFF_FINALIZE_ID, &ret_value, &ret_value, &hg_req) < 0)
+ return FAIL;
+
+ HG_Wait(hg_req, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE);
+
+ /* Free Mercury request */
+ if(HG_Request_free(hg_req) != HG_SUCCESS)
+ return FAIL;
+
+ /* Free addr id */
+ if (NA_SUCCESS != NA_Addr_free(network_class, PEER))
+ return FAIL;
+
+ /* Finalize interface */
+ //if (HG_SUCCESS != HG_Bulk_finalize())
+ //return FAIL;
+
+ if (HG_SUCCESS != HG_Finalize())
+ return FAIL;
+
+ if(NA_SUCCESS != NA_Finalize(network_class))
+ return FAIL;
+
+ return ret_value;
+} /* end EFF_finalize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_fapl_iod
+ *
+ * Purpose: Modify the file access property list to use the H5VL_IOD
+ * plugin defined in this source file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fapl_iod(hid_t fapl_id, MPI_Comm comm, MPI_Info info)
+{
+ H5VL_iod_fapl_t fa;
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iMcMi", fapl_id, comm, info);
+
+ if(fapl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ if(MPI_COMM_NULL == comm)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid communicator")
+
+ /* Initialize driver specific properties */
+ fa.comm = comm;
+ fa.info = info;
+
+ ret_value = H5P_set_vol(plist, &H5VL_iod_g, &fa);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_fapl_iod() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_fapl_copy
+ *
+ * Purpose: Copies the iod-specific file access properties.
+ *
+ * Return: Success: Ptr to a new property list
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_fapl_copy(const void *_old_fa)
+{
+ const H5VL_iod_fapl_t *old_fa = (const H5VL_iod_fapl_t*)_old_fa;
+ H5VL_iod_fapl_t *new_fa = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (new_fa = (H5VL_iod_fapl_t *)H5MM_malloc(sizeof(H5VL_iod_fapl_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* Copy the general information */
+ /* HDmemcpy(new_fa, old_fa, sizeof(H5VL_iod_fapl_t)); */
+
+ /* Duplicate communicator and Info object. */
+ if(FAIL == H5FD_mpi_comm_info_dup(old_fa->comm, old_fa->info, &new_fa->comm, &new_fa->info))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "Communicator/Info duplicate failed");
+
+ ret_value = new_fa;
+
+done:
+ if (NULL == ret_value){
+ /* cleanup */
+ if (new_fa)
+ H5MM_xfree(new_fa);
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_fapl_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_fapl_free
+ *
+ * Purpose: Frees the iod-specific file access properties.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * July 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_fapl_free(void *_fa)
+{
+ herr_t ret_value = SUCCEED;
+ H5VL_iod_fapl_t *fa = (H5VL_iod_fapl_t*)_fa;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ assert(fa);
+
+ /* Free the internal communicator and INFO object */
+ assert(MPI_COMM_NULL!=fa->comm);
+ if(H5FD_mpi_comm_info_free(&fa->comm, &fa->info) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "Communicator/Info free failed");
+ /* free the struct */
+ H5MM_xfree(fa);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_fapl_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_ocpl_enable_checksum
+ *
+ * Purpose: Set a boolean flag on the object creation property list
+ * to indicate to the VOL plugin to enable checksum on the
+ * object to be created.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_ocpl_enable_checksum(hid_t ocpl_id, hbool_t flag)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ib", ocpl_id, flag);
+
+ if(ocpl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a ocpl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5O_CRT_ENABLE_CHECKSUM_NAME, &flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_ocpl_enable_checksum() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_ocpl_enable_checksum
+ *
+ * Purpose: Retrieve a boolean flag on the object creation property
+ * list that indicates whether checksuming on this object
+ * is enabled or not.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_ocpl_enable_checksum(hid_t ocpl_id, hbool_t *flag/*out*/)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", ocpl_id, flag);
+
+ if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a ocpl")
+
+ /* Get the transfer mode */
+ if(flag)
+ if(H5P_get(plist, H5O_CRT_ENABLE_CHECKSUM_NAME, flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_ocpl_enable_checksum() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_lapl_replica_id
+ *
+ * Purpose: Set the replica ID to be used when accessing an object
+ * using this access plist.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_lapl_replica_id(hid_t lapl_id, hrpl_t replica_id)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iRp", lapl_id, replica_id);
+
+ if(lapl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a lapl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5O_ACS_REPLICA_ID_NAME, &replica_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_lapl_replica_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_lapl_replica_id
+ *
+ * Purpose: Retrieve the replica ID from this access plist.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_lapl_replica_id(hid_t lapl_id, hrpl_t *replica_id/*out*/)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", lapl_id, replica_id);
+
+ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a lapl")
+
+ /* Get the transfer mode */
+ if(replica_id)
+ if(H5P_get(plist, H5O_ACS_REPLICA_ID_NAME, replica_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_lapl_replica_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dxpl_checksum
+ *
+ * Purpose: Modify the dataset transfer property list to set a
+ * checksum value for the data to be transfered.
+ * This is used with write operations.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dxpl_checksum(hid_t dxpl_id, uint64_t cs)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iIl", dxpl_id, cs);
+
+ if(dxpl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5D_XFER_CHECKSUM_NAME, &cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set checksum value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dxpl_checksum() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_dxpl_checksum
+ *
+ * Purpose: Retrieve the checksum value that was set using
+ * H5Pset_dxpl_checksum.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dxpl_checksum(hid_t dxpl_id, uint64_t *cs/*out*/)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", dxpl_id, cs);
+
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Get the transfer mode */
+ if(cs)
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_NAME, cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_dxpl_checksum() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dxpl_checksum_ptr
+ *
+ * Purpose: Set a pointer to tell the library where to insert the
+ * checksum that is received from a remote location.
+ * This is used with read operations.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dxpl_checksum_ptr(hid_t dxpl_id, uint64_t *cs)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Il", dxpl_id, cs);
+
+ if(dxpl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5D_XFER_CHECKSUM_PTR_NAME, &cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set checksum_ptr value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dxpl_checksum_ptr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_dxpl_checksum_ptr
+ *
+ * Purpose: Retrieve the checksum pointer value that was set using
+ * H5Pset_dxpl_checksum_ptr.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dxpl_checksum_ptr(hid_t dxpl_id, uint64_t **cs/*out*/)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", dxpl_id, cs);
+
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Get the transfer mode */
+ if(cs)
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_PTR_NAME, *cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum_ptr value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_dxpl_checksum_ptr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_metadata_integrity_scope
+ *
+ * Purpose: Set the scope of checksum generation and verification for
+ * metadata in the FF stack. This is a file access property so the
+ * property is set on a particular container. Changing the property
+ * would require closing the file and reopening it. Possible values
+ * for this property are:
+ * H5_CHECKSUM_NONE = No metadata checksuming and verification
+ is done at any part of the stack.
+ * H5_CHECKSUM_TRANSFER = Metadata is verified after being transfered
+ through Mercury.
+ * H5_CHECKSUM_IOD = Metadata is checksumed and the checksum is
+ given to IOD when written, and verified when read.
+ * H5_CHECKSUM_MEMORY = Metadata is verified when moved in memory
+ (Not currently supported).
+ * H5_CHECKSUM_ALL = Metadata is checksumed and verified on all levels.
+ *
+ * Note that the property value is a bitflag so any combination can be
+ * set for individual values using OR operation.
+ *
+ * Return: Non-negative
+ * on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_metadata_integrity_scope(hid_t fapl_id, uint32_t scope)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iIu", fapl_id, scope);
+
+ if(scope > H5_CHECKSUM_ALL)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid scope for Data Integrity");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set property */
+ if(H5P_set(plist, H5VL_CS_BITFLAG_NAME, &scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data integrity scope");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_metadata_integrity_scope() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_metadata_integrity_scope
+ *
+ * Purpose: Get the current bit flag indicating the data integrity scope.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_metadata_integrity_scope(hid_t fapl_id, uint32_t *scope)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Iu", fapl_id, scope);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ if(scope) {
+ /* Get property */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_metadata_integrity_scope() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_rawdata_integrity_scope
+ *
+ * Purpose: Set the scope of checksum generation and verification for
+ * rawdata in the FF stack. This is a data transfer property so the
+ * property is set on a particular I/O operation (H5Dread/write,
+ * H5Mset/get, etc ...). Possible values for this property are:
+ * H5_CHECKSUM_NONE = No checksuming and verification
+ is done at any part of the stack.
+ * H5_CHECKSUM_TRANSFER = Data is verified after being transfered
+ through Mercury.
+ * H5_CHECKSUM_IOD = Data is checksumed and the checksum is
+ given to IOD when written, and verified when read.
+ * H5_CHECKSUM_MEMORY = Data is verified when moved in memory
+ * H5_CHECKSUM_ALL = Data is checksumed and verified on all levels.
+ *
+ * Note that the property value is a bitflag so any combination can be
+ * set for individual values using OR operation.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_rawdata_integrity_scope(hid_t dxpl_id, uint32_t scope)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iIu", dxpl_id, scope);
+
+ if(scope > H5_CHECKSUM_ALL)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid scope for Data Integrity");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* Set property */
+ if(H5P_set(plist, H5VL_CS_BITFLAG_NAME, &scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data integrity scope");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_rawdata_integrity_scope() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_rawdata_integrity_scope
+ *
+ * Purpose: Get the current bit flag indicating the data integrity scope.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_rawdata_integrity_scope(hid_t dxpl_id, uint32_t *scope)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*Iu", dxpl_id, scope);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ if(scope) {
+ /* Get property */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_rawdata_integrity_scope() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dxpl_inject_corruption
+ *
+ * Purpose: Temporary routine to set a boolean flag that tells the
+ * library to inject corruption in the stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dxpl_inject_corruption(hid_t dxpl_id, hbool_t flag)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ib", dxpl_id, flag);
+
+ if(dxpl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5D_XFER_INJECT_CORRUPTION_NAME, &flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dxpl_inject_corruption() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_dxpl_inject_corruption
+ *
+ * Purpose: Temporary routine to retrieve the boolean flag that tells the
+ * library to inject corruption in the stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dxpl_inject_corruption(hid_t dxpl_id, hbool_t *flag/*out*/)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", dxpl_id, flag);
+
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl")
+
+ /* Get the transfer mode */
+ if(flag)
+ if(H5P_get(plist, H5D_XFER_INJECT_CORRUPTION_NAME, flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_dxpl_inject_corruption() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dcpl_append_only
+ *
+ * Purpose: Set a boolean flag on the dataset creation property list
+ * to indicate to the VOL plugin that access to this dataset
+ * will always be in an append/sequence only manner.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dcpl_append_only(hid_t dcpl_id, hbool_t flag)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ib", dcpl_id, flag);
+
+ if(dcpl_id == H5P_DEFAULT)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't set values in default property list")
+
+ /* Check arguments */
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dcpl")
+
+ /* Set the transfer mode */
+ if(H5P_set(plist, H5D_CRT_APPEND_ONLY_NAME, &flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dcpl_append_only() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_dcpl_append_only
+ *
+ * Purpose: Retrieve a boolean flag on the dataset creation property list
+ * that indicates whether access to this dataset
+ * will always be in an append/sequence only manner.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dcpl_append_only(hid_t dcpl_id, hbool_t *flag/*out*/)
+{
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", dcpl_id, flag);
+
+ if(NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dcpl")
+
+ /* Get the transfer mode */
+ if(flag)
+ if(H5P_get(plist, H5D_CRT_APPEND_ONLY_NAME, flag) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_dcpl_append_only() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_analysis_execute
+ *
+ * Purpose: Creates a file as a iod HDF5 file.
+ *
+ * Return: Success: the file id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_analysis_execute(const char *file_name, const char *obj_name,
+ hid_t query_id, const char *split_script, const char *combine_script,
+ void **req)
+{
+ analysis_execute_in_t input;
+ analysis_execute_out_t *output;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* set the input structure for the HG encode routine */
+ input.file_name = file_name;
+ input.obj_name = obj_name;
+ input.query_id = query_id;
+ input.split_script = split_script;
+ input.combine_script = combine_script;
+
+#if H5VL_IOD_DEBUG
+ printf("Analysis Execute on file %s Object %s\n",
+ input.file_name, input.obj_name);
+#endif
+
+ if(NULL == (output = (analysis_execute_out_t *)H5MM_malloc(sizeof(analysis_execute_out_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate analysis output struct");
+
+ if(H5VL__iod_create_and_forward(H5VL_ANALYSIS_EXECUTE_ID, HG_ANALYSIS_EXECUTE,
+ NULL, 0, 0, NULL,
+ NULL, &input, output, output, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship file create");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_analysis_execute() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_file_create
+ *
+ * Purpose: Creates a file as a iod HDF5 file.
+ *
+ * Return: Success: the file id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
+ hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_fapl_t *fa = NULL;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ H5VL_iod_file_t *file = NULL;
+ file_create_in_t input;
+ uint32_t cs_scope;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /*
+ * Adjust bit flags by turning on the creation bit and making sure that
+ * the EXCL or TRUNC bit is set. All newly-created files are opened for
+ * reading and writing.
+ */
+ if(0==(flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC)))
+ flags |= H5F_ACC_EXCL; /*default*/
+ flags |= H5F_ACC_RDWR | H5F_ACC_CREAT;
+
+ /* obtain the process rank from the communicator attached to the fapl ID */
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
+ if(NULL == (fa = (H5VL_iod_fapl_t *)H5P_get_vol_info(plist)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't get IOD info struct")
+
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get scope for data integrity checks");
+
+ /* allocate the file object that is returned to the user */
+ if(NULL == (file = H5FL_CALLOC(H5VL_iod_file_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD file struct");
+ file->remote_file.root_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ file->remote_file.root_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ file->remote_file.root_id = IOD_OBJ_INVALID;
+ file->remote_file.c_version = 0;
+
+ MPI_Comm_rank(fa->comm, &file->my_rank);
+ MPI_Comm_size(fa->comm, &file->num_procs);
+
+ if(0 == file->my_rank) {
+ file->remote_file.kv_oid_index = 4;
+ file->remote_file.array_oid_index = 0;
+ file->remote_file.blob_oid_index = 0;
+ }
+ else {
+ file->remote_file.kv_oid_index = 0;
+ file->remote_file.array_oid_index = 0;
+ file->remote_file.blob_oid_index = 0;
+ }
+
+ /* Duplicate communicator and Info object. */
+ if(FAIL == H5FD_mpi_comm_info_dup(fa->comm, fa->info, &file->comm, &file->info))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "Communicator/Info duplicate failed");
+
+ /* Generate an IOD ID for the root group to be created */
+ H5VL_iod_gen_obj_id(0, file->num_procs, (uint64_t)0, IOD_OBJ_KV, &input.root_id);
+ file->remote_file.root_id = input.root_id;
+
+ /* Generate an IOD ID for the root group MDKV to be created */
+ H5VL_iod_gen_obj_id(0, file->num_procs, (uint64_t)1, IOD_OBJ_KV, &input.mdkv_id);
+ file->remote_file.mdkv_id = input.mdkv_id;
+
+ /* Generate an IOD ID for the root group ATTR KV to be created */
+ H5VL_iod_gen_obj_id(0, file->num_procs, (uint64_t)2, IOD_OBJ_KV, &input.attrkv_id);
+ file->remote_file.attrkv_id = input.attrkv_id;
+
+ /* Generate an IOD ID for the OID index array to be created */
+ H5VL_iod_gen_obj_id(0, file->num_procs, (uint64_t)3, IOD_OBJ_KV, &input.oidkv_id);
+ file->remote_file.oidkv_id = input.oidkv_id;
+
+ /* set the input structure for the HG encode routine */
+ input.name = name;
+ input.num_peers = (uint32_t)file->num_procs;
+ input.flags = flags;
+ input.fcpl_id = fcpl_id;
+ input.fapl_id = fapl_id;
+
+ /* create the file object that is passed to the API layer */
+ file->file_name = HDstrdup(name);
+ file->flags = flags;
+ file->md_integrity_scope = cs_scope;
+ if((file->remote_file.fcpl_id = H5Pcopy(fcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fcpl");
+ if((file->fapl_id = H5Pcopy(fapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl");
+ file->nopen_objs = 1;
+ file->num_req = 0;
+
+ /* initialize head and tail of the container's linked list of requests */
+ file->request_list_head = NULL;
+ file->request_list_tail = NULL;
+
+ file->common.obj_type = H5I_FILE;
+ /* The name of the location is the root's object name "\" */
+ file->common.obj_name = HDstrdup("/");
+ file->common.obj_name[1] = '\0';
+ file->common.file = file;
+
+#if H5VL_IOD_DEBUG
+ printf("File Create %s IOD ROOT ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.root_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_FILE_CREATE_ID, HG_FILE_CREATE,
+ (H5VL_iod_object_t *)file, 1, 0, NULL,
+ NULL, &input, &file->remote_file, file, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship file create");
+
+ ret_value = (void *)file;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(file->file_name) {
+ HDfree(file->file_name);
+ file->file_name = NULL;
+ }
+ if(file->common.obj_name) {
+ HDfree(file->common.obj_name);
+ file->common.obj_name = NULL;
+ }
+ if(file->common.comment) {
+ HDfree(file->common.comment);
+ file->common.comment = NULL;
+ }
+ if(file->comm || file->info)
+ if(H5FD_mpi_comm_info_free(&file->comm, &file->info) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "Communicator/Info free failed")
+ if(file->fapl_id != FAIL && H5I_dec_ref(file->fapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(file->remote_file.fcpl_id != FAIL &&
+ H5I_dec_ref(file->remote_file.fcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(file != NULL) {
+ file = H5FL_FREE(H5VL_iod_file_t, file);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_file_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_file_open
+ *
+ * Purpose: Opens a file as a iod HDF5 file.
+ *
+ * Return: Success: file id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_file_open(const char *name, unsigned flags, hid_t fapl_id,
+ hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_fapl_t *fa;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ H5VL_iod_file_t *file = NULL;
+ file_open_in_t input;
+ hid_t rcxt_id;
+ uint32_t cs_scope;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* obtain the process rank from the communicator attached to the fapl ID */
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
+ if(NULL == (fa = (H5VL_iod_fapl_t *)H5P_get_vol_info(plist)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't get IOD info struct")
+
+ /* determine if we want to acquire the latest readable version
+ when the file is opened */
+ if(H5P_get(plist, H5VL_ACQUIRE_RC_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't set property value for rxct id")
+
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get scope for data integrity checks");
+
+ if(FAIL != rcxt_id) {
+ input.acquire = TRUE;
+ }
+ else {
+ input.acquire = FALSE;
+ }
+
+ /* allocate the file object that is returned to the user */
+ if(NULL == (file = H5FL_CALLOC(H5VL_iod_file_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD file struct");
+
+ file->remote_file.coh.cookie = IOD_OH_UNDEFINED;
+ file->remote_file.root_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ file->remote_file.root_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ file->remote_file.root_id = IOD_OBJ_INVALID;
+ file->remote_file.mdkv_id = IOD_OBJ_INVALID;
+ file->remote_file.attrkv_id = IOD_OBJ_INVALID;
+ file->remote_file.oidkv_id = IOD_OBJ_INVALID;
+ file->remote_file.fcpl_id = -1;
+ file->remote_file.c_version = IOD_TID_UNKNOWN;
+ file->remote_file.kv_oid_index = 0;
+ file->remote_file.array_oid_index = 0;
+ file->remote_file.blob_oid_index = 0;
+
+ /* set input paramters in struct to give to the function shipper */
+ input.name = name;
+ input.flags = flags;
+ input.fapl_id = fapl_id;
+
+ /* create the file object that is passed to the API layer */
+ MPI_Comm_rank(fa->comm, &file->my_rank);
+ MPI_Comm_size(fa->comm, &file->num_procs);
+ /* Duplicate communicator and Info object. */
+ if(FAIL == H5FD_mpi_comm_info_dup(fa->comm, fa->info, &file->comm, &file->info))
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "Communicator/Info duplicate failed");
+
+ file->file_name = HDstrdup(name);
+ file->flags = flags;
+ file->md_integrity_scope = cs_scope;
+ if((file->fapl_id = H5Pcopy(fapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl");
+ file->nopen_objs = 1;
+ file->num_req = 0;
+
+ /* initialize head and tail of the container's linked list */
+ file->request_list_head = NULL;
+ file->request_list_tail = NULL;
+
+ file->common.obj_type = H5I_FILE;
+ /* The name of the location is the root's object name "\" */
+ file->common.obj_name = HDstrdup("/");
+ file->common.obj_name[1] = '\0';
+ file->common.file = file;
+
+#if H5VL_IOD_DEBUG
+ printf("File Open %s axe id %"PRIu64"\n", name, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_FILE_OPEN_ID, HG_FILE_OPEN,
+ (H5VL_iod_object_t *)file, 1, 0, NULL,
+ NULL, &input, &file->remote_file, file, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship file open");
+
+ ret_value = (void *)file;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(file->file_name) {
+ HDfree(file->file_name);
+ file->file_name = NULL;
+ }
+ if(file->common.obj_name) {
+ HDfree(file->common.obj_name);
+ file->common.obj_name = NULL;
+ }
+ if(file->common.comment) {
+ HDfree(file->common.comment);
+ file->common.comment = NULL;
+ }
+ if(file->comm || file->info)
+ if(H5FD_mpi_comm_info_free(&file->comm, &file->info) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "Communicator/Info free failed")
+
+ if(file->fapl_id != FAIL && H5I_dec_ref(file->fapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(file->remote_file.fcpl_id != FAIL &&
+ H5I_dec_ref(file->remote_file.fcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(file != NULL) {
+ file = H5FL_FREE(H5VL_iod_file_t, file);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_file_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_file_get
+ *
+ * Purpose: Gets certain data about a file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_file_get(void *_obj, H5VL_file_get_t get_type, hid_t UNUSED dxpl_id,
+ void UNUSED **req, va_list arguments)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ H5VL_iod_file_t *file = obj->file;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch (get_type) {
+ /* H5Fget_access_plist */
+ case H5VL_FILE_GET_FAPL:
+ {
+ H5VL_iod_fapl_t fa, *old_fa;
+ H5P_genplist_t *new_plist, *old_plist;
+ hid_t *plist_id = va_arg (arguments, hid_t *);
+
+ /* Retrieve the file's access property list */
+ if((*plist_id = H5Pcopy(file->fapl_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list")
+
+ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+ if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(file->fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
+
+ if(NULL == (old_fa = (H5VL_iod_fapl_t *)H5P_get_vol_info(old_plist)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get vol info");
+ fa.comm = old_fa->comm;
+ fa.info = old_fa->info;
+
+ ret_value = H5P_set_vol(new_plist, &H5VL_iod_g, &fa);
+
+ break;
+ }
+ /* H5Fget_create_plist */
+ case H5VL_FILE_GET_FCPL:
+ {
+ hid_t *plist_id = va_arg (arguments, hid_t *);
+
+ /* Retrieve the file's access property list */
+ if((*plist_id = H5Pcopy(file->remote_file.fcpl_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file creation property list")
+
+ break;
+ }
+ /* H5Fget_intent */
+ case H5VL_FILE_GET_INTENT:
+ {
+ unsigned *ret = va_arg (arguments, unsigned *);
+
+ if(file->flags & H5F_ACC_RDWR)
+ *ret = H5F_ACC_RDWR;
+ else
+ *ret = H5F_ACC_RDONLY;
+ break;
+ }
+ /* H5Fget_name */
+ case H5VL_FILE_GET_NAME:
+ {
+ H5I_type_t UNUSED type = va_arg (arguments, H5I_type_t);
+ size_t size = va_arg (arguments, size_t);
+ char *name = va_arg (arguments, char *);
+ ssize_t *ret = va_arg (arguments, ssize_t *);
+ size_t len;
+
+ len = HDstrlen(file->file_name);
+
+ if(name) {
+ HDstrncpy(name, file->file_name, MIN(len + 1,size));
+ if(len >= size)
+ name[size-1]='\0';
+ } /* end if */
+
+ /* Set the return value for the API call */
+ *ret = (ssize_t)len;
+ break;
+ }
+ /* H5I_get_file_id */
+ case H5VL_OBJECT_GET_FILE:
+ {
+
+ H5I_type_t UNUSED type = va_arg (arguments, H5I_type_t);
+ void **ret = va_arg (arguments, void **);
+
+ *ret = (void*)file;
+ break;
+ }
+ /* H5Fget_obj_count */
+ case H5VL_FILE_GET_OBJ_COUNT:
+ {
+ //unsigned types = va_arg (arguments, unsigned);
+ //ssize_t *ret = va_arg (arguments, ssize_t *);
+ //break;
+ }
+ /* H5Fget_obj_ids */
+ case H5VL_FILE_GET_OBJ_IDS:
+ {
+ //unsigned types = va_arg (arguments, unsigned);
+ //size_t max_objs = va_arg (arguments, size_t);
+ //hid_t *oid_list = va_arg (arguments, hid_t *);
+ //ssize_t *ret = va_arg (arguments, ssize_t *);
+ //break;
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_file_get() */
+
+#if 0
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_file_misc
+ *
+ * Purpose: Perform an operation
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_file_misc(void *obj, H5VL_file_misc_t misc_type, hid_t dxpl_id,
+ void **req, va_list arguments)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch (misc_type) {
+ /* H5Fis_accessible */
+ case H5VL_FILE_IS_ACCESSIBLE:
+ {
+ hid_t fapl_id = va_arg (arguments, hid_t);
+ const char *name = va_arg (arguments, const char *);
+ htri_t *ret = va_arg (arguments, htri_t *);
+ H5VL_iod_file_t *file = NULL;
+#if 0
+ /* attempt to open the file through the MDS plugin */
+ if(NULL == (file = (H5VL_iod_file_t *)H5VL_iod_file_open(name, H5F_ACC_RDONLY, fapl_id,
+ H5_REQUEST_NULL)))
+ *ret = FALSE;
+ else
+ *ret = TRUE;
+
+ /* close the file if it was succesfully opened */
+ if(file && H5VL_iod_file_close((void*)file, H5_REQUEST_NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close file");
+ break;
+#endif
+ }
+ /* H5Fmount */
+ case H5VL_FILE_MOUNT:
+ {
+ H5I_type_t type = va_arg (arguments, H5I_type_t);
+ const char *name = va_arg (arguments, const char *);
+ H5VL_iod_file_t *child = va_arg (arguments, H5VL_iod_file_t *);
+ hid_t plist_id = va_arg (arguments, hid_t);
+ }
+ /* H5Fmount */
+ case H5VL_FILE_UNMOUNT:
+ {
+ H5I_type_t type = va_arg (arguments, H5I_type_t);
+ const char *name = va_arg (arguments, const char *);
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "MDS Plugin does not support this operation type")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_file_misc() */
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_file_close
+ *
+ * Purpose: Closes a file.
+ *
+ * Return: Success: 0
+ * Failure: -1, file not closed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_file_close(void *_file, hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_file_t *file = (H5VL_iod_file_t *)_file;
+ file_close_in_t input;
+ int *status = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_all(file) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ /* allocate an integer to receive the return value if the file close succeeded or not */
+ status = (int *)malloc(sizeof(int));
+
+ /* determine the max indexes for the KV, Array, and BLOB IDs used
+ up by all the processes */
+ if(file->flags != H5F_ACC_RDONLY) {
+ uint64_t input_indexes[3] = {file->remote_file.kv_oid_index,
+ file->remote_file.array_oid_index,
+ file->remote_file.blob_oid_index};
+ uint64_t object_indexes[3];
+
+ if(MPI_SUCCESS != MPI_Reduce(input_indexes, object_indexes, 3,
+ MPI_UINT64_T, MPI_MAX, 0, file->comm))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't determine max value of object indexes for ID generation");
+
+ if(0 == file->my_rank) {
+ input.max_kv_index = object_indexes[0];
+ input.max_array_index = object_indexes[1];
+ input.max_blob_index = object_indexes[2];
+ }
+ else {
+ input.max_kv_index = 0;
+ input.max_array_index = 0;
+ input.max_blob_index = 0;
+ }
+ }
+ else {
+ input.max_kv_index = 0;
+ input.max_array_index = 0;
+ input.max_blob_index = 0;
+ }
+
+ input.coh = file->remote_file.coh;
+ input.root_oh = file->remote_file.root_oh;
+ input.root_id = file->remote_file.root_id;
+ input.cs_scope = file->md_integrity_scope;
+
+ if(file->num_req) {
+ H5VL_iod_request_t *cur_req = file->request_list_head;
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * file->num_req)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+
+ while(cur_req) {
+ if(cur_req->state == H5VL_IOD_PENDING) {
+ parent_reqs[num_parents] = cur_req;
+ cur_req->ref_count ++;
+ num_parents ++;
+ }
+ cur_req = cur_req->file_next;
+ }
+ }
+
+#if H5VL_IOD_DEBUG
+ printf("File Close Root ID %"PRIu64" axe id %"PRIu64"\n", input.root_id, g_axe_id);
+#endif
+
+ /*
+ * All ranks must wait for rank 0 to go close the file and write
+ * out the metadata before going on an closing the file. Rank 0
+ * calls the barrier on request completion in
+ * H5VLiod_client.c.
+
+ * (This is an IOD limitation.)
+ */
+ if(0 != file->my_rank)
+ MPI_Barrier (file->comm);
+
+ if(H5VL__iod_create_and_forward(H5VL_FILE_CLOSE_ID, HG_FILE_CLOSE,
+ (H5VL_iod_object_t *)file, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship file close");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_file_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_group_create
+ *
+ * Purpose: Creates a group inside a iod h5 file.
+ *
+ * Return: Success: group
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_group_create(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name, hid_t gcpl_id,
+ hid_t gapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the group */
+ H5VL_iod_group_t *grp = NULL; /* the group object that is created and passed to the user */
+ group_create_in_t input;
+ hid_t lcpl_id;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5P_genplist_t *plist = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get the group creation plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ /* get creation properties */
+ if(H5P_get(plist, H5VL_GRP_LCPL_ID, &lcpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id");
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the group object that is returned to the user */
+ if(NULL == (grp = H5FL_CALLOC(H5VL_iod_group_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ grp->remote_group.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ grp->remote_group.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+
+ /* Generate IOD IDs for the group to be created */
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.grp_id);
+ grp->remote_group.iod_id = input.grp_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.mdkv_id);
+ grp->remote_group.mdkv_id = input.mdkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.attrkv_id);
+ grp->remote_group.attrkv_id = input.attrkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.gcpl_id = gcpl_id;
+ input.gapl_id = gapl_id;
+ input.lcpl_id = lcpl_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ /* setup the local group struct */
+ /* store the entire path of the group locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (grp->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(grp->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(grp->common.obj_name+obj_name_len, name, name_len);
+ grp->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* copy property lists */
+ if((grp->remote_group.gcpl_id = H5Pcopy(gcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy gcpl");
+ if((grp->gapl_id = H5Pcopy(gapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy gapl");
+ /* set common object parameters */
+ grp->common.obj_type = H5I_GROUP;
+ grp->common.file = obj->file;
+ grp->common.file->nopen_objs ++;
+
+#if H5VL_IOD_DEBUG
+ printf("Group Create %s, IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.grp_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_GROUP_CREATE_ID, HG_GROUP_CREATE,
+ (H5VL_iod_object_t *)grp, 1,
+ num_parents, parent_reqs, (H5VL_iod_req_info_t *)tr,
+ &input, &grp->remote_group, grp, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship group create");
+
+ ret_value = (void *)grp;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(grp->common.obj_name) {
+ HDfree(grp->common.obj_name);
+ grp->common.obj_name = NULL;
+ }
+ if(grp->common.comment) {
+ HDfree(grp->common.comment);
+ grp->common.comment = NULL;
+ }
+ if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != FAIL &&
+ H5I_dec_ref(grp->remote_group.gcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp)
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_group_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_group_open
+ *
+ * Purpose: Opens a group inside a iod h5 file.
+ *
+ * Return: Success: group id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_group_open(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t gapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the group */
+ H5VL_iod_group_t *grp = NULL; /* the group object that is created and passed to the user */
+ group_open_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the group object that is returned to the user */
+ if(NULL == (grp = H5FL_CALLOC(H5VL_iod_group_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ grp->remote_group.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ grp->remote_group.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ grp->remote_group.iod_id = IOD_OBJ_INVALID;
+ grp->remote_group.mdkv_id = IOD_OBJ_INVALID;
+ grp->remote_group.attrkv_id = IOD_OBJ_INVALID;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.gapl_id = gapl_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Group Open %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.loc_id, g_axe_id);
+#endif
+
+ /* setup the local group struct */
+ /* store the entire path of the group locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (grp->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(grp->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(grp->common.obj_name+obj_name_len, name, name_len);
+ grp->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* copy property lists */
+ if((grp->gapl_id = H5Pcopy(gapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy gapl");
+ /* set common object parameters */
+ grp->common.obj_type = H5I_GROUP;
+ grp->common.file = obj->file;
+ grp->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_GROUP_OPEN_ID, HG_GROUP_OPEN,
+ (H5VL_iod_object_t *)grp, 1,
+ num_parents, parent_reqs, (H5VL_iod_req_info_t *)rc,
+ &input, &grp->remote_group, grp, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship group open");
+
+ ret_value = (void *)grp;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(grp->common.obj_name) {
+ HDfree(grp->common.obj_name);
+ grp->common.obj_name = NULL;
+ }
+ if(grp->common.comment) {
+ HDfree(grp->common.comment);
+ grp->common.comment = NULL;
+ }
+ if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != FAIL &&
+ H5I_dec_ref(grp->remote_group.gcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp)
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_group_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_group_get
+ *
+ * Purpose: Gets certain data about a group
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_group_get(void *_grp, H5VL_group_get_t get_type, hid_t UNUSED dxpl_id,
+ void UNUSED **req, va_list arguments)
+{
+ H5VL_iod_group_t *grp = (H5VL_iod_group_t *)_grp;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch (get_type) {
+ /* H5Gget_create_plist */
+ case H5VL_GROUP_GET_GCPL:
+ {
+ hid_t *plist_id = va_arg (arguments, hid_t *);
+
+ /* Retrieve the file's access property list */
+ if((*plist_id = H5Pcopy(grp->remote_group.gcpl_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group create property list")
+ break;
+ }
+ /* H5Gget_info */
+ case H5VL_GROUP_GET_INFO:
+ {
+ //H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t);
+ //H5G_info_t *ginfo = va_arg (arguments, H5G_info_t *);
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from group")
+ }
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_group_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_group_close
+ *
+ * Purpose: Closes a group.
+ *
+ * Return: Success: 0
+ * Failure: -1, group not closed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_group_close(void *_grp, hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_group_t *grp = (H5VL_iod_group_t *)_grp;
+ group_close_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(grp->common.file, grp) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(IOD_OH_UNDEFINED == grp->remote_group.iod_oh.rd_oh.cookie) {
+ /* Synchronously wait on the request attached to the group */
+ if(H5VL_iod_request_wait(grp->common.file, grp->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on group request");
+ grp->common.request = NULL;
+ }
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)grp, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)grp, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parent requests");
+ }
+
+ input.iod_oh = grp->remote_group.iod_oh;
+ input.iod_id = grp->remote_group.iod_id;
+
+ /* allocate an integer to receive the return value if the group close succeeded or not */
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Group Close IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ input.iod_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_GROUP_CLOSE_ID, HG_GROUP_CLOSE,
+ (H5VL_iod_object_t *)grp, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship group close");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_group_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_create
+ *
+ * Purpose: Sends a request to the IOD to create a dataset
+ *
+ * Return: Success: dataset object.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_dataset_create(void *_obj, H5VL_loc_params_t UNUSED loc_params,
+ const char *name, hid_t dcpl_id,
+ hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the dataset */
+ H5VL_iod_dset_t *dset = NULL; /* the dataset object that is created and passed to the user */
+ dset_create_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5P_genplist_t *plist = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ hid_t type_id, space_id, lcpl_id;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get the dcpl plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+
+ /* get datatype, dataspace, and lcpl IDs that were added in the dcpl at the API layer */
+ if(H5P_get(plist, H5VL_DSET_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id");
+ if(H5P_get(plist, H5VL_DSET_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id");
+ if(H5P_get(plist, H5VL_DSET_LCPL_ID, &lcpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id");
+
+ /* Check that no values other than the first dimension in MAX dims
+ is H5S_UNLIMITED. */
+ {
+ H5S_t *ds = NULL;
+ int ndims, i;
+ hsize_t max_dims[H5S_MAX_RANK];
+
+ if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a dataspace")
+
+ ndims = (int)H5S_GET_EXTENT_NDIMS(ds);
+ H5S_get_simple_extent_dims(ds, NULL, max_dims);
+
+ for(i=1; i<ndims; i++) {
+ if(max_dims[i] == H5S_UNLIMITED)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "only first dimension can be H5S_UNLIMITED.");
+ }
+ }
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* Retrieve the parent AXE id by traversing the path where the
+ dataset should be created. */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_iod_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dset->remote_dset.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_id = IOD_OBJ_INVALID;
+
+ /* Generate IOD IDs for the dset to be created */
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.array_oid_index,
+ IOD_OBJ_ARRAY, &input.dset_id);
+ dset->remote_dset.iod_id = input.dset_id;
+ /* increment the index of ARRAY objects created on the container */
+ obj->file->remote_file.array_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.mdkv_id);
+ dset->remote_dset.mdkv_id = input.mdkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.attrkv_id);
+ dset->remote_dset.attrkv_id = input.attrkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.dcpl_id = dcpl_id;
+ input.dapl_id = dapl_id;
+ input.lcpl_id = lcpl_id;
+ input.type_id = type_id;
+ input.space_id = space_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (dset->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dset->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dset->common.obj_name+obj_name_len, name, name_len);
+ dset->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* copy property lists, dtype, and dspace*/
+ if((dset->remote_dset.dcpl_id = H5Pcopy(dcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dcpl");
+ if((dset->dapl_id = H5Pcopy(dapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+ if((dset->remote_dset.type_id = H5Tcopy(type_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dtype");
+ if((dset->remote_dset.space_id = H5Scopy(space_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dspace");
+
+ /* set common object parameters */
+ dset->common.obj_type = H5I_DATASET;
+ dset->common.file = obj->file;
+ dset->common.file->nopen_objs ++;
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset Create %s IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.dset_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_CREATE_ID, HG_DSET_CREATE,
+ (H5VL_iod_object_t *)dset, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, &dset->remote_dset, dset, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship dataset create");
+
+ ret_value = (void *)dset;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(dset->common.obj_name) {
+ HDfree(dset->common.obj_name);
+ dset->common.obj_name = NULL;
+ }
+ if(dset->common.comment) {
+ HDfree(dset->common.comment);
+ dset->common.comment = NULL;
+ }
+ if(dset->remote_dset.type_id != FAIL && H5I_dec_ref(dset->remote_dset.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dset->remote_dset.space_id != FAIL && H5I_dec_ref(dset->remote_dset.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(dset->remote_dset.dcpl_id != FAIL && H5I_dec_ref(dset->remote_dset.dcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset)
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_open
+ *
+ * Purpose: Sends a request to the IOD to open a dataset
+ *
+ * Return: Success: dataset object.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_dataset_open(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the dataset */
+ H5VL_iod_dset_t *dset = NULL; /* the dataset object that is created and passed to the user */
+ dset_open_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for rcxt_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* Retrieve the parent AXE id by traversing the path where the
+ dataset should be opened. */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_iod_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dset->remote_dset.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_id = IOD_OBJ_INVALID;
+ dset->remote_dset.mdkv_id = IOD_OBJ_INVALID;
+ dset->remote_dset.attrkv_id = IOD_OBJ_INVALID;
+ dset->remote_dset.dcpl_id = -1;
+ dset->remote_dset.type_id = -1;
+ dset->remote_dset.space_id = -1;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.dapl_id = dapl_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (dset->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dset->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dset->common.obj_name+obj_name_len, name, name_len);
+ dset->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((dset->dapl_id = H5Pcopy(dapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+
+ /* set common object parameters */
+ dset->common.obj_type = H5I_DATASET;
+ dset->common.file = obj->file;
+ dset->common.file->nopen_objs ++;
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset Open %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.loc_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_OPEN_ID, HG_DSET_OPEN,
+ (H5VL_iod_object_t *)dset, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, &dset->remote_dset, dset, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship dataset open");
+
+ ret_value = (void *)dset;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ if(dset->common.obj_name) {
+ HDfree(dset->common.obj_name);
+ dset->common.obj_name = NULL;
+ }
+ if(dset->common.comment) {
+ HDfree(dset->common.comment);
+ dset->common.comment = NULL;
+ }
+ if(dset->remote_dset.type_id != FAIL && H5I_dec_ref(dset->remote_dset.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dset->remote_dset.space_id != FAIL && H5I_dec_ref(dset->remote_dset.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(dset->remote_dset.dcpl_id != FAIL && H5I_dec_ref(dset->remote_dset.dcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset)
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_read
+ *
+ * Purpose: Reads raw data from a dataset into a buffer.
+ *
+ * Return: Success: 0
+ * Failure: -1, data not read.
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, void *buf, void **req)
+{
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset;
+ dset_io_in_t input;
+ H5P_genplist_t *plist = NULL;
+ hg_bulk_t *bulk_handle = NULL;
+ H5S_t *mem_space = NULL;
+ H5S_t *file_space = NULL;
+ char fake_char;
+ size_t type_size; /* size of mem type */
+ hssize_t nelmts; /* num elements in mem dataspace */
+ H5VL_iod_read_info_t *info = NULL;
+ H5VL_iod_read_status_t *status = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5VL_iod_type_info_t *type_info = NULL;
+ char *vl_lengths = NULL;
+ size_t vl_lengths_size = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the dataset that is not present locally, wait */
+ if(-1 == dset->remote_dset.dcpl_id ||
+ -1 == dset->remote_dset.type_id ||
+ -1 == dset->remote_dset.space_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ dset->common.request = NULL;
+ }
+
+ /* check arguments */
+ if(H5S_ALL != mem_space_id) {
+ if(NULL == (mem_space = (H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_SELECT_VALID(mem_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ else {
+ if(NULL == (mem_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ if(H5S_select_all(mem_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ }
+
+ if(H5S_ALL != file_space_id) {
+ if(NULL == (file_space = (H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_SELECT_VALID(file_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ else {
+ if(NULL == (file_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ if(H5S_select_all(file_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ }
+
+ if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
+
+ if(!buf)
+ buf = &fake_char;
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID")
+
+ /* At the IOD server, the array object is actually created with
+ MAX dims, not current dims. So here we need to range check the
+ filespace against the current dimensions of the dataset to make
+ sure that the I/O happens in the current range and not the
+ extensible one. */
+ {
+ H5S_t *dset_space;
+ hsize_t dset_dims[H5S_MAX_RANK], io_dims[H5S_MAX_RANK];
+ int dset_ndims, io_ndims, i;
+
+ if(NULL == (dset_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ dset_ndims = (int)H5S_GET_EXTENT_NDIMS(dset_space);
+ io_ndims = (int)H5S_GET_EXTENT_NDIMS(file_space);
+
+ if(dset_ndims < io_ndims)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection not within dataset's dataspace");
+
+ H5S_get_simple_extent_dims(dset_space, dset_dims, NULL);
+ H5S_get_simple_extent_dims(file_space, io_dims, NULL);
+
+ for(i=0 ; i<io_ndims ; i++) {
+ if(dset_dims[i] < io_dims[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection Out of range");
+ }
+ }
+
+ /* get the memory type size */
+ {
+ H5T_t *dt = NULL;
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+
+ type_size = H5T_GET_SIZE(dt);
+ }
+
+ /* get the number of elements selcted in dataspace */
+ nelmts = H5S_GET_SELECT_NPOINTS(mem_space);
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (bulk_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a buld data transfer handle");
+
+ if(NULL == (type_info = (H5VL_iod_type_info_t *)H5MM_malloc(sizeof(H5VL_iod_type_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate type info struct");
+
+ /* Get type info */
+ if(H5VL_iod_get_type_info(mem_type_id, type_info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to get datatype info");
+
+ /* Check if there are any vlen types. If so, guess number of vl
+ * lengths, allocate array, and register with bulk buffer. Otherwise,
+ * register data buffer. */
+ if(type_info->vls) {
+ /* For now, just guess one segment for each vl in top level */
+ vl_lengths_size = 8 * (size_t)nelmts * type_info->num_vls;
+
+ /* Allocate vl_lengths */
+ if(NULL == (vl_lengths = (char *)HDmalloc(vl_lengths_size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate vlen lengths buffer");
+
+ /* Register vl_lengths buffer */
+ HG_Bulk_handle_create(vl_lengths, vl_lengths_size, HG_BULK_READWRITE, bulk_handle);
+ } /* end if */
+ else {
+ /* for non vlen data, create the bulk handle to recieve the data in */
+ if(H5VL_iod_pre_read(mem_type_id, mem_space, buf, nelmts, bulk_handle) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't generate read parameters");
+ }
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)dset, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure for reading data */
+ input.coh = dset->common.file->remote_file.coh;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.mdkv_id = dset->remote_dset.mdkv_id;
+ input.bulk_handle = *bulk_handle;
+ input.vl_len_bulk_handle = HG_BULK_NULL;
+ input.checksum = 0;
+ input.dxpl_id = dxpl_id;
+ if(H5S_ALL == file_space_id)
+ input.space_id = dset->remote_dset.space_id;
+ else
+ input.space_id = file_space_id;
+ input.dset_type_id = dset->remote_dset.type_id;
+ input.mem_type_id = mem_type_id;
+ input.trans_num = 0;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = dset->common.file->md_integrity_scope;
+ input.axe_id = g_axe_id;
+
+ /* allocate structure to receive status of read operation
+ (contains return value, checksum, and buffer size) */
+ if(NULL == (status = (H5VL_iod_read_status_t *)H5MM_malloc(sizeof(H5VL_iod_read_status_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate Read status struct");
+
+ /* setup info struct for I/O request.
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_read_info_t *)H5MM_calloc(sizeof(H5VL_iod_read_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request");
+
+ info->status = status;
+ info->bulk_handle = bulk_handle;
+ info->type_info = type_info;
+ info->vl_lengths = vl_lengths;
+ info->vl_lengths_size = vl_lengths_size;
+ info->buf_ptr = buf;
+ info->nelmts = nelmts;
+ info->type_size = type_size;
+ info->cs_ptr = NULL;
+ info->axe_id = g_axe_id;
+
+ /* store a copy of the dataspace selection to be able to calculate the checksum later */
+ if(NULL == (info->space = H5S_copy(mem_space, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace");
+ /* store the pointer to the buffer where the checksum needs to be placed */
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_PTR_NAME, &info->cs_ptr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum pointer value");
+ /* store the raw data integrity scope */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &info->raw_cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum pointer value");
+
+ /* If the read is of VL data, then we need the read parameters to
+ perform the actual read when the wait is called (i.e. when we
+ retrieve the buffer size) */
+ if(type_info->vls) {
+ if((info->file_space_id = H5Scopy(input.space_id)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace");
+ if((info->mem_type_id = H5Tcopy(mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype");
+ if((info->dxpl_id = H5P_copy_plist((H5P_genplist_t *)plist, TRUE)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy dxpl");
+
+ info->ion_target = PEER;
+ info->read_id = H5VL_DSET_READ_ID;
+ }
+
+#if H5VL_IOD_DEBUG
+ if(!type_info->vls)
+ printf("Dataset Read, axe id %"PRIu64"\n", g_axe_id);
+ else
+ printf("Dataset GET size, axe id %"PRIu64"\n", g_axe_id + 1);
+#endif
+
+ /* forward the call to the IONs */
+ if(!type_info->vls) {
+ if(H5VL__iod_create_and_forward(H5VL_DSET_READ_ID, HG_DSET_READ,
+ (H5VL_iod_object_t *)dset, 0,
+ num_parents, parent_reqs, (H5VL_iod_req_info_t *)rc,
+ &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship dataset read");
+ }
+ else {
+ /* allocate an axe_id for the read operation to follow */
+ g_axe_id ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_GET_VL_SIZE_ID, HG_DSET_GET_VL_SIZE,
+ (H5VL_iod_object_t *)dset, 0,
+ num_parents, parent_reqs, (H5VL_iod_req_info_t *)rc,
+ &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship dataset get VL size");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_write
+ *
+ * Purpose: Writes raw data from a buffer into a dataset.
+ *
+ * Return: Success: 0
+ * Failure: -1, dataset not writed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req)
+{
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset;
+ dset_io_in_t input;
+ H5P_genplist_t *plist = NULL;
+ hg_bulk_t *bulk_handle = NULL;
+ hg_bulk_t *vl_len_bulk_handle = NULL;
+ hg_bulk_segment_t *vl_segments = NULL;
+ char *vl_lengths = NULL;
+ H5S_t *mem_space = NULL;
+ H5S_t *file_space = NULL;
+ char fake_char;
+ int *status = NULL;
+ H5VL_iod_write_info_t *info; /* info struct used to manage I/O parameters once the operation completes*/
+ uint64_t internal_cs = 0; /* internal checksum calculated in this function */
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ uint64_t user_cs, vl_len_cs;
+ uint32_t raw_cs_scope = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the dataset that is not present locally, wait */
+ if(-1 == dset->remote_dset.dcpl_id ||
+ -1 == dset->remote_dset.type_id ||
+ -1 == dset->remote_dset.space_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ dset->common.request = NULL;
+ }
+
+ /* check arguments */
+ if(H5S_ALL != mem_space_id) {
+ if(NULL == (mem_space = (H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_SELECT_VALID(mem_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ else {
+ if(NULL == (mem_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ if(H5S_select_all(mem_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ }
+
+ if(H5S_ALL != file_space_id) {
+ if(NULL == (file_space = (H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_SELECT_VALID(file_space) != TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ else {
+ if(NULL == (file_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ if(H5S_select_all(file_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ }
+
+ if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
+
+ if(!buf)
+ buf = &fake_char;
+
+ /* At the IOD server, the array object is actually created with
+ MAX dims, not current dims. So here we need to range check the
+ filespace against the current dimensions of the dataset to make
+ sure that the I/O happens in the current range and not the
+ extensible one. */
+ {
+ H5S_t *dset_space;
+ hsize_t dset_dims[H5S_MAX_RANK], io_dims[H5S_MAX_RANK];
+ int dset_ndims, io_ndims, i;
+
+ if(NULL == (dset_space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ dset_ndims = (int)H5S_GET_EXTENT_NDIMS(dset_space);
+ io_ndims = (int)H5S_GET_EXTENT_NDIMS(file_space);
+
+ if(dset_ndims < io_ndims)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection not within dataset's dataspace");
+
+ H5S_get_simple_extent_dims(dset_space, dset_dims, NULL);
+ H5S_get_simple_extent_dims(file_space, io_dims, NULL);
+
+ for(i=0 ; i<io_ndims ; i++) {
+ if(dset_dims[i] < io_dims[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection Out of range");
+ }
+ }
+
+ /* get the plist pointer */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* get the TR object */
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* get the data integrity scope */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &raw_cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (bulk_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a buld data transfer handle");
+ if(NULL == (vl_len_bulk_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a buld data transfer handle");
+
+ if(raw_cs_scope) {
+ /* compute checksum and create bulk handle */
+ if(H5VL_iod_pre_write(mem_type_id, mem_space, buf, &internal_cs, &vl_len_cs,
+ bulk_handle, vl_len_bulk_handle, &vl_segments, &vl_lengths) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't generate write parameters");
+ }
+ else {
+#if H5VL_IOD_DEBUG
+ printf("NO DATA INTEGRITY CHECKS ON RAW DATA WRITTEN\n");
+#endif
+ /* compute checksum and create bulk handle */
+ if(H5VL_iod_pre_write(mem_type_id, mem_space, buf, NULL, NULL, bulk_handle,
+ vl_len_bulk_handle, &vl_segments, &vl_lengths) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't generate write parameters");
+ internal_cs = 0;
+ }
+
+ /* Verify the checksum value if the dxpl contains a user defined checksum */
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_NAME, &user_cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum value");
+
+ if((raw_cs_scope & H5_CHECKSUM_MEMORY) && user_cs &&
+ user_cs != internal_cs) {
+ fprintf(stderr, "Errrr.. In memory Data corruption. expecting %016lX, got %016lX\n",
+ user_cs, internal_cs);
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "Checksum verification failed");
+ }
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)dset, (H5VL_iod_req_info_t *)tr,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = dset->common.file->remote_file.coh;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.mdkv_id = dset->remote_dset.mdkv_id;
+ input.bulk_handle = *bulk_handle;
+ input.vl_len_bulk_handle = *vl_len_bulk_handle;
+ input.checksum = internal_cs;
+ input.dxpl_id = dxpl_id;
+ if(H5S_ALL == file_space_id)
+ input.space_id = dset->remote_dset.space_id;
+ else
+ input.space_id = file_space_id;
+ input.dset_type_id = dset->remote_dset.type_id;
+ input.mem_type_id = mem_type_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = dset->common.file->md_integrity_scope;
+ input.axe_id = g_axe_id;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset Write, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ /* setup info struct for I/O request
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_write_info_t *)H5MM_calloc(sizeof(H5VL_iod_write_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request");
+ info->status = status;
+ info->bulk_handle = bulk_handle;
+ info->vl_len_bulk_handle = vl_len_bulk_handle;
+ info->vl_lengths = vl_lengths;
+ info->vl_segments = vl_segments;
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_WRITE_ID, HG_DSET_WRITE,
+ (H5VL_iod_object_t *)dset, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship dataset write");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_set_extent
+ *
+ * Purpose: Set Extent of dataset
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[],
+ hid_t dxpl_id, void **req)
+{
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset;
+ dset_set_extent_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5P_genplist_t *plist = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the dataset that is not present locally, wait */
+ if(-1 == dset->remote_dset.space_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ dset->common.request = NULL;
+ }
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dset, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dset, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parent requests");
+ }
+
+ /* Fill input structure */
+ input.coh = dset->common.file->remote_file.coh;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.mdkv_id = dset->remote_dset.mdkv_id;
+ input.dims.rank = H5Sget_simple_extent_ndims(dset->remote_dset.space_id);
+ input.dims.size = size;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = dset->common.file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset Set Extent, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_SET_EXTENT_ID, HG_DSET_SET_EXTENT,
+ (H5VL_iod_object_t *)dset, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship dataset set_extent");
+
+ /* modify the local dataspace of the dataset */
+ {
+ H5S_t *space; /* Dataset's dataspace */
+
+ if(NULL == (space = (H5S_t *)H5I_object_verify(dset->remote_dset.space_id,
+ H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Modify the size of the data space */
+ if(H5S_set_extent(space, size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space");
+ }
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_set_extent() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_get
+ *
+ * Purpose: Gets certain information about a dataset
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_dataset_get(void *_dset, H5VL_dataset_get_t get_type,
+ hid_t UNUSED dxpl_id,
+ void UNUSED **req, va_list arguments)
+{
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(-1 == dset->remote_dset.dcpl_id ||
+ -1 == dset->remote_dset.type_id ||
+ -1 == dset->remote_dset.space_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ dset->common.request = NULL;
+ }
+
+ switch (get_type) {
+ case H5VL_DATASET_GET_DCPL:
+ {
+ hid_t *plist_id = va_arg (arguments, hid_t *);
+
+ /* Retrieve the file's access property list */
+ if((*plist_id = H5Pcopy(dset->remote_dset.dcpl_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dset creation property list")
+
+ break;
+ }
+ case H5VL_DATASET_GET_DAPL:
+ {
+ hid_t *plist_id = va_arg (arguments, hid_t *);
+
+ /* Retrieve the file's access property list */
+ if((*plist_id = H5Pcopy(dset->dapl_id)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dset access property list")
+
+ break;
+ }
+ case H5VL_DATASET_GET_SPACE:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+
+ if((*ret_id = H5Scopy(dset->remote_dset.space_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get dataspace ID of dataset");
+ break;
+ }
+ case H5VL_DATASET_GET_SPACE_STATUS:
+ {
+ H5D_space_status_t *allocation = va_arg (arguments, H5D_space_status_t *);
+
+ *allocation = H5D_SPACE_STATUS_NOT_ALLOCATED;
+ break;
+ }
+ case H5VL_DATASET_GET_TYPE:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+
+ if((*ret_id = H5Tcopy(dset->remote_dset.type_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of dataset")
+ }
+ case H5VL_DATASET_GET_STORAGE_SIZE:
+ case H5VL_DATASET_GET_OFFSET:
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from dataset")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_dataset_close
+ *
+ * Purpose: Closes a dataset.
+ *
+ * Return: Success: 0
+ * Failure: -1, dataset not closed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_dataset_close(void *_dset, hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset;
+ dset_close_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(-1 == dset->remote_dset.dcpl_id ||
+ -1 == dset->remote_dset.type_id ||
+ -1 == dset->remote_dset.space_id ||
+ IOD_OH_UNDEFINED == dset->remote_dset.iod_oh.rd_oh.cookie) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait dset request");
+ dset->common.request = NULL;
+ }
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(dset->common.file, dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dset, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dset, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parent requests");
+ }
+
+ input.iod_oh = dset->remote_dset.iod_oh;
+ input.iod_id = dset->remote_dset.iod_id;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset Close IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ input.iod_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_DSET_CLOSE_ID, HG_DSET_CLOSE,
+ (H5VL_iod_object_t *)dset, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship dataset close");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_dataset_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_datatype_commit
+ *
+ * Purpose: Commits a datatype inside the container.
+ *
+ * Return: Success: datatype
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_datatype_commit(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the datatype */
+ H5VL_iod_dtype_t *dtype = NULL; /* the datatype object that is created and passed to the user */
+ dtype_commit_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the datatype object that is returned to the user */
+ if(NULL == (dtype = H5FL_CALLOC(H5VL_iod_dtype_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dtype->remote_dtype.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_id = IOD_OBJ_INVALID;
+
+ /* Generate IOD IDs for the group to be created */
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.blob_oid_index,
+ IOD_OBJ_BLOB, &input.dtype_id);
+ dtype->remote_dtype.iod_id = input.dtype_id;
+ /* increment the index of BLOB objects created on the container */
+ obj->file->remote_file.blob_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.mdkv_id);
+ dtype->remote_dtype.mdkv_id = input.mdkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.attrkv_id);
+ dtype->remote_dtype.attrkv_id = input.attrkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.tcpl_id = tcpl_id;
+ input.tapl_id = tapl_id;
+ input.lcpl_id = lcpl_id;
+ input.type_id = type_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Datatype Commit %s IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.dtype_id, g_axe_id);
+#endif
+
+ /* setup the local datatype struct */
+ /* store the entire path of the datatype locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (dtype->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dtype->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dtype->common.obj_name+obj_name_len, name, name_len);
+ dtype->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* store a copy of the datatype parameters*/
+ if((dtype->remote_dtype.tcpl_id = H5Pcopy(tcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dcpl");
+ if((dtype->tapl_id = H5Pcopy(tapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+ if((dtype->remote_dtype.type_id = H5Tcopy(type_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dtype");
+
+ /* set common object parameters */
+ dtype->common.obj_type = H5I_DATATYPE;
+ dtype->common.file = obj->file;
+ dtype->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_DTYPE_COMMIT_ID, HG_DTYPE_COMMIT,
+ (H5VL_iod_object_t *)dtype, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, &dtype->remote_dtype, dtype, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship datatype commit");
+
+ ret_value = (void *)dtype;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free dtype components */
+ if(dtype->common.obj_name) {
+ HDfree(dtype->common.obj_name);
+ dtype->common.obj_name = NULL;
+ }
+ if(dtype->common.comment) {
+ HDfree(dtype->common.comment);
+ dtype->common.comment = NULL;
+ }
+ if(dtype->remote_dtype.tcpl_id != FAIL && H5I_dec_ref(dtype->remote_dtype.tcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->tapl_id != FAIL && H5I_dec_ref(dtype->tapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->remote_dtype.type_id != FAIL && H5I_dec_ref(dtype->remote_dtype.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dtype)
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_datatype_commit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_datatype_open
+ *
+ * Purpose: Opens a named datatype.
+ *
+ * Return: Success: datatype id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_datatype_open(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t tapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the datatype */
+ H5VL_iod_dtype_t *dtype = NULL; /* the datatype object that is created and passed to the user */
+ dtype_open_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the datatype object that is returned to the user */
+ if(NULL == (dtype = H5FL_CALLOC(H5VL_iod_dtype_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dtype->remote_dtype.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_id = IOD_OBJ_INVALID;
+ dtype->remote_dtype.mdkv_id = IOD_OBJ_INVALID;
+ dtype->remote_dtype.attrkv_id = IOD_OBJ_INVALID;
+ dtype->remote_dtype.tcpl_id = -1;
+ dtype->remote_dtype.type_id = -1;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.tapl_id = tapl_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Datatype Open %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.loc_id, g_axe_id);
+#endif
+
+ /* setup the local datatype struct */
+ /* store the entire path of the datatype locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (dtype->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dtype->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dtype->common.obj_name+obj_name_len, name, name_len);
+ dtype->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((dtype->tapl_id = H5Pcopy(tapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy tapl");
+
+ /* set common object parameters */
+ dtype->common.obj_type = H5I_DATATYPE;
+ dtype->common.file = obj->file;
+ dtype->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_DTYPE_OPEN_ID, HG_DTYPE_OPEN,
+ (H5VL_iod_object_t *)dtype, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, &dtype->remote_dtype, dtype, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship datatype open");
+
+ ret_value = (void *)dtype;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free dtype components */
+ if(dtype->common.obj_name) {
+ HDfree(dtype->common.obj_name);
+ dtype->common.obj_name = NULL;
+ }
+ if(dtype->common.comment) {
+ HDfree(dtype->common.comment);
+ dtype->common.comment = NULL;
+ }
+ if(dtype->remote_dtype.tcpl_id != FAIL && H5I_dec_ref(dtype->remote_dtype.tcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->tapl_id != FAIL && H5I_dec_ref(dtype->tapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->remote_dtype.type_id != FAIL && H5I_dec_ref(dtype->remote_dtype.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dtype)
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_datatype_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_datatype_get_binary
+ *
+ * Purpose: gets size required to encode the datatype
+ *
+ * Return: Success: datatype id.
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static ssize_t
+H5VL_iod_datatype_get_binary(void *obj, unsigned char *buf, size_t size,
+ hid_t UNUSED dxpl_id, void UNUSED **req)
+{
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)obj;
+ size_t nalloc = size;
+ ssize_t ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(H5Tencode(dtype->remote_dtype.type_id, buf, &nalloc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine serialized length of datatype")
+
+ ret_value = (ssize_t) nalloc;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_datatype_get_binary() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_datatype_get
+ *
+ * Purpose: Gets certain information about a datatype
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * June, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_datatype_get(void UNUSED *obj, H5VL_datatype_get_t get_type,
+ hid_t UNUSED dxpl_id, void UNUSED **req, va_list UNUSED arguments)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch (get_type) {
+ /* H5Tget_create_plist */
+ case H5VL_DATATYPE_GET_TCPL:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+ H5P_genplist_t *tcpl_plist = NULL; /* New datatype creation property list */
+ hid_t tcpl_id;
+
+ /* Copy the default datatype creation property list */
+ if(NULL == (tcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATATYPE_CREATE_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default creation property list")
+ if((tcpl_id = H5P_copy_plist(tcpl_plist, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to copy the creation property list")
+
+ *ret_id = tcpl_id;
+ break;
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from datatype")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_datatype_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_datatype_close
+ *
+ * Purpose: Closes an datatype.
+ *
+ * Return: Success: 0
+ * Failure: -1, datatype not closed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_datatype_close(void *obj, hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)obj;
+ dtype_close_in_t input;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ int *status = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(dtype->common.file, dtype) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(IOD_OH_UNDEFINED == dtype->remote_dtype.iod_oh.rd_oh.cookie) {
+ /* Synchronously wait on the request attached to the dtype */
+ if(H5VL_iod_request_wait(dtype->common.file, dtype->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on dtype request");
+ dtype->common.request = NULL;
+ }
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dtype, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)dtype, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parent requests");
+ }
+
+ input.iod_oh = dtype->remote_dtype.iod_oh;
+ input.iod_id = dtype->remote_dtype.iod_id;
+
+#if H5VL_IOD_DEBUG
+ printf("Datatype Close IOD ID %"PRIu64", axe id %"PRIu64"\n", input.iod_id, g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_DTYPE_CLOSE_ID, HG_DTYPE_CLOSE,
+ (H5VL_iod_object_t *)dtype, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship datatype open");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_datatype_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_create
+ *
+ * Purpose: Sends a request to the IOD to create a attribute
+ *
+ * Return: Success: attribute object.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_attribute_create(void *_obj, H5VL_loc_params_t loc_params, const char *attr_name,
+ hid_t acpl_id, hid_t UNUSED aapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the attribute */
+ H5VL_iod_attr_t *attr = NULL; /* the attribute object that is created and passed to the user */
+ attr_create_in_t input;
+ H5P_genplist_t *plist = NULL;
+ iod_obj_id_t iod_id, attrkv_id;
+ iod_handles_t iod_oh;
+ const char *path; /* path on where the traversal starts relative to the location object specified */
+ char *loc_name = NULL;
+ hid_t type_id, space_id;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get the acpl plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+
+ /* get datatype, dataspace, and lcpl IDs that were added in the acpl at the API layer */
+ if(H5P_get(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id");
+ if(H5P_get(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id");
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the attribute object that is returned to the user */
+ if(NULL == (attr = H5FL_CALLOC(H5VL_iod_attr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ attr->remote_attr.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ attr->remote_attr.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+
+ /* Generate IOD IDs for the attr to be created */
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.array_oid_index,
+ IOD_OBJ_ARRAY, &input.attr_id);
+ attr->remote_attr.iod_id = input.attr_id;
+ /* increment the index of ARRAY objects created on the container */
+ obj->file->remote_file.array_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.mdkv_id);
+ attr->remote_attr.mdkv_id = input.mdkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_attrkv_id = attrkv_id;
+ input.loc_oh = iod_oh;
+ input.path = loc_name;
+ input.attr_name = attr_name;
+ input.type_id = type_id;
+ input.space_id = space_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ /* setup the local attribute struct */
+ /* store the entire path of the attribute locally */
+ if(loc_params.type == H5VL_OBJECT_BY_SELF) {
+ path = NULL;
+ attr->loc_name = HDstrdup(obj->obj_name);
+ }
+ else if (loc_params.type == H5VL_OBJECT_BY_NAME &&
+ (NULL != obj->obj_name)) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len;
+
+ path = loc_params.loc_data.loc_by_name.name;
+ name_len = HDstrlen(path);
+
+ if (NULL == (attr->loc_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(attr->loc_name, obj->obj_name, obj_name_len);
+ HDmemcpy(attr->loc_name+obj_name_len, path, name_len);
+ attr->loc_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* store the name of the attribute locally */
+ attr->common.obj_name = strdup(attr_name);
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Create %s IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ attr_name, input.attr_id, g_axe_id);
+#endif
+
+ /* copy dtype, and dspace */
+ if((attr->remote_attr.type_id = H5Tcopy(type_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dtype");
+ if((attr->remote_attr.space_id = H5Scopy(space_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dspace");
+
+ /* set common object parameters */
+ attr->common.obj_type = H5I_ATTR;
+ attr->common.file = obj->file;
+ attr->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_CREATE_ID, HG_ATTR_CREATE,
+ (H5VL_iod_object_t *)attr, 1, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, &attr->remote_attr,
+ attr, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship attribute create");
+
+ ret_value = (void *)attr;
+
+done:
+ if(loc_name)
+ HDfree(loc_name);
+
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free attr components */
+ if(attr->common.obj_name) {
+ HDfree(attr->common.obj_name);
+ attr->common.obj_name = NULL;
+ }
+ if(attr->common.comment) {
+ HDfree(attr->common.comment);
+ attr->common.comment = NULL;
+ }
+ if(attr->loc_name) {
+ HDfree(attr->loc_name);
+ attr->loc_name = NULL;
+ }
+ if(attr->remote_attr.type_id != FAIL && H5I_dec_ref(attr->remote_attr.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(attr->remote_attr.space_id != FAIL && H5I_dec_ref(attr->remote_attr.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(attr)
+ attr = H5FL_FREE(H5VL_iod_attr_t, attr);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_open
+ *
+ * Purpose: Sends a request to the IOD to open a attribute
+ *
+ * Return: Success: attribute object.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_attribute_open(void *_obj, H5VL_loc_params_t loc_params, const char *attr_name,
+ hid_t UNUSED aapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the attribute */
+ H5VL_iod_attr_t *attr = NULL; /* the attribute object that is created and passed to the user */
+ attr_open_in_t input;
+ const char *path; /* path on where the traversal starts relative to the location object specified */
+ char *loc_name = NULL;
+ iod_obj_id_t iod_id, attrkv_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the attribute object that is returned to the user */
+ if(NULL == (attr = H5FL_CALLOC(H5VL_iod_attr_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ attr->remote_attr.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ attr->remote_attr.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ attr->remote_attr.iod_id = IOD_OBJ_INVALID;
+ attr->remote_attr.mdkv_id = IOD_OBJ_INVALID;
+ attr->remote_attr.type_id = -1;
+ attr->remote_attr.space_id = -1;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_attrkv_id = attrkv_id;
+ input.loc_oh = iod_oh;
+ input.path = loc_name;
+ input.attr_name = attr_name;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Open %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ attr_name, input.loc_id, g_axe_id);
+#endif
+
+ /* setup the local attribute struct */
+
+ /* store the entire path of the attribute locally */
+ if(loc_params.type == H5VL_OBJECT_BY_SELF) {
+ path = NULL;
+ attr->loc_name = HDstrdup(obj->obj_name);
+ }
+ else if (loc_params.type == H5VL_OBJECT_BY_NAME &&
+ NULL != obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len;
+
+ path = loc_params.loc_data.loc_by_name.name;
+ name_len = HDstrlen(path);
+
+ if (NULL == (attr->loc_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(attr->loc_name, obj->obj_name, obj_name_len);
+ HDmemcpy(attr->loc_name+obj_name_len, path, name_len);
+ attr->loc_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* store the name of the attribute locally */
+ attr->common.obj_name = strdup(attr_name);
+
+ /* set common object parameters */
+ attr->common.obj_type = H5I_ATTR;
+ attr->common.file = obj->file;
+ attr->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_OPEN_ID, HG_ATTR_OPEN,
+ (H5VL_iod_object_t *)attr, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, &attr->remote_attr, attr, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship attribute open");
+
+ ret_value = (void *)attr;
+
+done:
+ if(loc_name)
+ HDfree(loc_name);
+
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free attr components */
+ if(attr->common.obj_name) {
+ HDfree(attr->common.obj_name);
+ attr->common.obj_name = NULL;
+ }
+ if(attr->common.comment) {
+ HDfree(attr->common.comment);
+ attr->common.comment = NULL;
+ }
+ if(attr->loc_name) {
+ HDfree(attr->loc_name);
+ attr->loc_name = NULL;
+ }
+ if(attr->remote_attr.type_id != FAIL && H5I_dec_ref(attr->remote_attr.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(attr->remote_attr.space_id != FAIL && H5I_dec_ref(attr->remote_attr.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(attr)
+ attr = H5FL_FREE(H5VL_iod_attr_t, attr);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_read
+ *
+ * Purpose: Reads raw data from a attribute into a buffer.
+ *
+ * Return: Success: 0
+ * Failure: -1, data not read.
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_attribute_read(void *_attr, hid_t type_id, void *buf, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)_attr;
+ attr_io_in_t input;
+ hg_bulk_t *bulk_handle = NULL;
+ int *status = NULL;
+ size_t size;
+ H5VL_iod_attr_io_info_t *info = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5P_genplist_t *plist = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID")
+
+ if(-1 == attr->remote_attr.space_id) {
+ HDassert(attr->common.request);
+ /* Synchronously wait on the request attached to the attribute */
+ if(H5VL_iod_request_wait(attr->common.file, attr->common.request) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't wait on HG request");
+ attr->common.request = NULL;
+ }
+
+ /* MSC - VLEN datatypes for attributes are not supported for now. */
+ {
+ H5T_class_t dt_class;
+ H5T_t *dt = NULL;
+
+ 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);
+ if(H5T_VLEN == dt_class || (H5T_STRING == dt_class && H5T_is_variable_str(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "VLEN datatypes for attributes not supported");
+ }
+
+ /* calculate the size of the buffer needed */
+ {
+ hsize_t nelmts;
+ size_t elmt_size;
+
+ nelmts = (hsize_t)H5Sget_simple_extent_npoints(attr->remote_attr.space_id);
+ elmt_size = H5Tget_size(type_id);
+
+ size = elmt_size * nelmts;
+ }
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (bulk_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't allocate a buld data transfer handle");
+
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(buf, size, HG_BULK_READWRITE, bulk_handle))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)attr, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = attr->common.file->remote_file.coh;
+ input.iod_oh = attr->remote_attr.iod_oh;
+ input.iod_id = attr->remote_attr.iod_id;
+ input.mdkv_id = attr->remote_attr.mdkv_id;
+ input.bulk_handle = *bulk_handle;
+ input.type_id = type_id;
+ input.space_id = attr->remote_attr.space_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = attr->common.file->md_integrity_scope;
+ input.trans_num = 0;
+
+ /* allocate structure to receive status of read operation (contains return value and checksum */
+ status = (int *)malloc(sizeof(int));
+
+ /* setup info struct for I/O request.
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_attr_io_info_t *)H5MM_malloc(sizeof(H5VL_iod_attr_io_info_t))))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't allocate a request");
+ info->status = status;
+ info->bulk_handle = bulk_handle;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Read IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ input.iod_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_READ_ID, HG_ATTR_READ,
+ (H5VL_iod_object_t *)attr, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute read");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_write
+ *
+ * Purpose: Writes raw data from a buffer into a attribute.
+ *
+ * Return: Success: 0
+ * Failure: -1, attribute not writed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_attribute_write(void *_attr, hid_t type_id, const void *buf, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)_attr;
+ attr_io_in_t input;
+ H5P_genplist_t *plist = NULL;
+ hg_bulk_t *bulk_handle = NULL;
+ int *status = NULL;
+ size_t size;
+ uint64_t internal_cs; /* internal checksum calculated in this function */
+ H5VL_iod_attr_io_info_t *info;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(-1 == attr->remote_attr.space_id) {
+ /* Synchronously wait on the request attached to the attribute */
+ if(H5VL_iod_request_wait(attr->common.file, attr->common.request) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't wait on HG request");
+ attr->common.request = NULL;
+ }
+
+ /* MSC - VLEN datatypes for attributes are not supported for now. */
+ {
+ H5T_class_t dt_class;
+ H5T_t *dt = NULL;
+
+ 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);
+ if(H5T_VLEN == dt_class || (H5T_STRING == dt_class && H5T_is_variable_str(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "VLEN datatypes for attributes not supported");
+ }
+
+ /* calculate the size of the buffer needed */
+ {
+ hsize_t nelmts;
+ size_t elmt_size;
+
+ nelmts = (hsize_t)H5Sget_simple_extent_npoints(attr->remote_attr.space_id);
+ elmt_size = H5Tget_size(type_id);
+
+ size = elmt_size * nelmts;
+ }
+
+ /* calculate a checksum for the data */
+ internal_cs = H5_checksum_crc64(buf, size);
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (bulk_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't allocate a bulk data transfer handle");
+
+ /* Register memory */
+ if(HG_SUCCESS != HG_Bulk_handle_create(buf, size, HG_BULK_READ_ONLY, bulk_handle))
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't create Bulk Data Handle");
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)attr, (H5VL_iod_req_info_t *)tr,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = attr->common.file->remote_file.coh;
+ input.iod_oh = attr->remote_attr.iod_oh;
+ input.iod_id = attr->remote_attr.iod_id;
+ input.mdkv_id = attr->remote_attr.mdkv_id;
+ input.bulk_handle = *bulk_handle;
+ input.type_id = type_id;
+ input.space_id = attr->remote_attr.space_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.checksum = internal_cs;
+ input.cs_scope = attr->common.file->md_integrity_scope;
+
+ status = (int *)malloc(sizeof(int));
+
+ /* setup info struct for I/O request
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_attr_io_info_t *)H5MM_malloc(sizeof(H5VL_iod_attr_io_info_t))))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't allocate a request");
+ info->status = status;
+ info->bulk_handle = bulk_handle;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Write IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ input.iod_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_WRITE_ID, HG_ATTR_WRITE,
+ (H5VL_iod_object_t *)attr, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute write");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_remove
+ *
+ * Purpose: Set Extent of attribute
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * October, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_attribute_remove(void *_obj, H5VL_loc_params_t loc_params, const char *attr_name,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the attribute */
+ attr_op_in_t input;
+ iod_obj_id_t iod_id, attrkv_id;
+ iod_handles_t iod_oh;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5P_genplist_t *plist = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ int *status = NULL;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.loc_id = iod_id;
+ input.loc_attrkv_id = attrkv_id;
+ input.loc_oh = iod_oh;
+ input.path = loc_name;
+ input.attr_name = attr_name;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Remove loc %s name %s, axe id %"PRIu64"\n",
+ loc_name, attr_name, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_REMOVE_ID, HG_ATTR_REMOVE,
+ (H5VL_iod_object_t *)obj, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute remove");
+
+done:
+ if(loc_name) {
+ HDfree(loc_name);
+ loc_name = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_get
+ *
+ * Purpose: Gets certain information about a attribute
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_attribute_get(void *_obj, H5VL_attr_get_t get_type, hid_t dxpl_id,
+ void **req, va_list arguments)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location of operation */
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID")
+
+ switch (get_type) {
+ /* H5Aget_space */
+ case H5VL_ATTR_GET_SPACE:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+
+ if(-1 == attr->remote_attr.space_id) {
+ /* Synchronously wait on the request attached to the attribute */
+ if(H5VL_iod_request_wait(attr->common.file, attr->common.request) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't wait on HG request");
+ attr->common.request = NULL;
+ }
+
+ if((*ret_id = H5Scopy(attr->remote_attr.space_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get dataspace ID of attribute")
+ break;
+ }
+ /* H5Aget_type */
+ case H5VL_ATTR_GET_TYPE:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+
+ if(-1 == attr->remote_attr.type_id) {
+ /* Synchronously wait on the request attached to the attribute */
+ if(H5VL_iod_request_wait(attr->common.file, attr->common.request) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't wait on HG request");
+ attr->common.request = NULL;
+ }
+
+ if((*ret_id = H5Tcopy(attr->remote_attr.type_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of attribute")
+ break;
+ }
+ /* H5Aget_create_plist */
+ case H5VL_ATTR_GET_ACPL:
+ {
+ hid_t *ret_id = va_arg (arguments, hid_t *);
+ //H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+
+ /* Retrieve the file's access property list */
+ if((*ret_id = H5Pcopy(H5P_ATTRIBUTE_CREATE_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get attr creation property list");
+ break;
+ }
+ /* H5Aget_name */
+ case H5VL_ATTR_GET_NAME:
+ {
+ 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 *);
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type) {
+ size_t copy_len, nbytes;
+
+ nbytes = HDstrlen(attr->common.obj_name);
+ HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/
+
+ /* compute the string length which will fit into the user's buffer */
+ copy_len = MIN(buf_size - 1, nbytes);
+
+ /* Copy all/some of the name */
+ if(buf && copy_len > 0) {
+ HDmemcpy(buf, attr->common.obj_name, copy_len);
+
+ /* Terminate the string */
+ buf[copy_len]='\0';
+ } /* end if */
+ *ret_val = (ssize_t)nbytes;
+ }
+ else if(H5VL_OBJECT_BY_IDX == loc_params.type) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr");
+ }
+ break;
+ }
+ /* H5Aexists/exists_by_name */
+ case H5VL_ATTR_EXISTS:
+ {
+ H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t);
+ char *attr_name = va_arg (arguments, char *);
+ htri_t *ret = va_arg (arguments, htri_t *);
+ attr_op_in_t input;
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &input.loc_attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, &input.loc_attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.attr_name = attr_name;
+ input.path = loc_name;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.trans_num = 0;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Exists loc %s name %s, axe id %"PRIu64"\n",
+ loc_name, attr_name, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_EXISTS_ID, HG_ATTR_EXISTS,
+ obj, 1, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input,
+ ret, ret, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute exists");
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Aget_info */
+ case H5VL_ATTR_GET_INFO:
+ {
+#if 0
+ H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t);
+ H5A_info_t *ainfo = va_arg (arguments, H5A_info_t *);
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get attr info")
+ }
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type) {
+ char *attr_name = va_arg (arguments, char *);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get attr info")
+ }
+ else if(H5VL_OBJECT_BY_IDX == loc_params.type) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get attr info")
+ }
+ else
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get attr info")
+#endif
+ break;
+ }
+ case H5VL_ATTR_GET_STORAGE_SIZE:
+ {
+ //hsize_t *ret = va_arg (arguments, hsize_t *);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get attr storage size");
+ break;
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from attr")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_attribute_close
+ *
+ * Purpose: Closes a attribute.
+ *
+ * Return: Success: 0
+ * Failure: -1, attribute not closed.
+ *
+ * Programmer: Mohamad Chaarawi
+ * March, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_attribute_close(void *_attr, hid_t UNUSED dxpl_id, void **req)
+{
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)_attr;
+ attr_close_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(-1 == attr->remote_attr.type_id ||
+ -1 == attr->remote_attr.space_id ||
+ IOD_OH_UNDEFINED == attr->remote_attr.iod_oh.rd_oh.cookie) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(attr->common.file, attr->common.request) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't wait on HG request");
+ attr->common.request = NULL;
+ }
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(attr->common.file, attr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)attr, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)attr, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parent requests");
+ }
+
+ status = (int *)malloc(sizeof(int));
+
+ input.iod_oh = attr->remote_attr.iod_oh;
+ input.iod_id = attr->remote_attr.iod_id;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Close IOD ID %"PRIu64", axe id %"PRIu64"\n", input.iod_id, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_CLOSE_ID, HG_ATTR_CLOSE,
+ (H5VL_iod_object_t *)attr, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute close");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_attribute_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_link_create
+ *
+ * Purpose: Creates an hard/soft/UD/external links.
+ * For now, only Hard and Soft Links are Supported.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_link_create(H5VL_link_create_type_t create_type, void *_obj, H5VL_loc_params_t loc_params,
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object */
+ link_create_in_t input;
+ int *status = NULL;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ char *link_value = NULL; /* Value of soft link */
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ char *loc_name = NULL, *target_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* Get the plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 3)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ status = (int *)malloc(sizeof(int));
+
+ switch (create_type) {
+ case H5VL_LINK_CREATE_HARD:
+ {
+ H5VL_iod_object_t *target_obj = NULL;
+ H5VL_loc_params_t target_params;
+
+ if(H5P_get(plist, H5VL_LINK_TARGET, &target_obj) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location");
+ if(H5P_get(plist, H5VL_LINK_TARGET_LOC_PARAMS, &target_params) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current name");
+
+ /* object is H5L_SAME_LOC */
+ if(NULL == obj && target_obj) {
+ obj = target_obj;
+ }
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* Retrieve the parent info by traversing the path where the
+ link should be created. */
+
+ /* object is H5L_SAME_LOC */
+ if(NULL == target_obj && obj) {
+ target_obj = obj;
+ }
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(target_obj, NULL,
+ &parent_reqs[num_parents], &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(target_obj, &input.target_loc_id,
+ &input.target_loc_oh, &input.target_mdkv_id, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.target_loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(target_obj->file, target_obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ target_obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(target_obj, &input.target_loc_id,
+ &input.target_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == target_params.type)
+ target_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == target_params.type)
+ target_name = strdup(target_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.create_type = H5VL_LINK_CREATE_HARD;
+ if(obj)
+ input.coh = obj->file->remote_file.coh;
+ else
+ input.coh = target_obj->file->remote_file.coh;
+
+ input.target_name = target_name;
+ input.loc_name = loc_name;
+ input.lcpl_id = lcpl_id;
+ input.lapl_id = lapl_id;
+ link_value = strdup("\0");
+ input.link_value = link_value;
+
+#if H5VL_IOD_DEBUG
+ printf("Link Create Hard axe id %"PRIu64"\n", g_axe_id);
+#endif
+ break;
+ }
+ case H5VL_LINK_CREATE_SOFT:
+ {
+ H5VL_iod_object_t *target_obj = NULL;
+ H5VL_loc_params_t target_params;
+
+ if(H5P_get(plist, H5VL_LINK_TARGET_NAME, &target_name) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for targe name");
+
+ target_params.type = H5VL_OBJECT_BY_NAME;
+ target_params.loc_data.loc_by_name.name = target_name;
+ target_params.loc_data.loc_by_name.plist_id = lapl_id;
+
+ if('/' == *target_name) {
+ /* The target location object is the file root */
+ target_obj = (H5VL_iod_object_t *)obj->file;
+ }
+ else {
+ target_obj = obj;
+ }
+
+ link_value = strdup(target_name);
+
+ /* Retrieve the parent info by traversing the path where the
+ link should be created from. */
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(target_obj, NULL,
+ &parent_reqs[num_parents], &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(target_obj, &input.target_loc_id,
+ &input.target_loc_oh, &input.target_mdkv_id, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.target_loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(target_obj->file, target_obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ target_obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(target_obj, &input.target_loc_id,
+ &input.target_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.create_type = H5VL_LINK_CREATE_SOFT;
+ input.coh = obj->file->remote_file.coh;
+ input.loc_name = loc_name;
+ input.target_name = target_name;
+ input.lcpl_id = lcpl_id;
+ input.lapl_id = lapl_id;
+ input.link_value = link_value;
+
+#if H5VL_IOD_DEBUG
+ printf("Link Create Soft axe id %"PRIu64"\n", g_axe_id);
+#endif
+ break;
+ }
+ /* MSC - not supported now */
+ case H5VL_LINK_CREATE_UD:
+ {
+ H5L_type_t link_type;
+ void *udata;
+ size_t udata_size;
+
+ if(H5P_get(plist, H5VL_LINK_TYPE, &link_type) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for link type");
+ if(H5P_get(plist, H5VL_LINK_UDATA, &udata) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata");
+ if(H5P_get(plist, H5VL_LINK_UDATA_SIZE, &udata_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata size");
+ }
+ default:
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "invalid link creation call")
+ }
+
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_CREATE_ID, HG_LINK_CREATE,
+ obj, 1, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link create");
+
+done:
+ if(link_value)
+ HDfree(link_value);
+ if(loc_name)
+ HDfree(loc_name);
+ if(H5VL_LINK_CREATE_HARD == create_type && target_name)
+ HDfree(target_name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_link_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_link_move
+ *
+ * Purpose: Renames an object within an HDF5 file and moves it to a new
+ * group. The original name SRC is unlinked from the group graph
+ * and then inserted with the new name DST (which can specify a
+ * new path for the object) as an atomic operation. The names
+ * are interpreted relative to SRC_LOC_ID and
+ * DST_LOC_ID, which are either file IDs or group ID.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_link_move(void *_src_obj, H5VL_loc_params_t loc_params1,
+ void *_dst_obj, H5VL_loc_params_t loc_params2,
+ hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *src_obj = (H5VL_iod_object_t *)_src_obj;
+ H5VL_iod_object_t *dst_obj = (H5VL_iod_object_t *)_dst_obj;
+ link_move_in_t input;
+ int *status = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5P_genplist_t *plist = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ char *src_name = NULL, *dst_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 3)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(src_obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(src_obj, &input.src_loc_id, &input.src_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.src_loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(src_obj->file, src_obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ src_obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(src_obj, &input.src_loc_id,
+ &input.src_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params1.type)
+ src_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params1.type)
+ src_name = strdup(loc_params1.loc_data.loc_by_name.name);
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(dst_obj, NULL, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(dst_obj, &input.dst_loc_id, &input.dst_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.dst_loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(dst_obj->file, dst_obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ dst_obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(dst_obj, &input.dst_loc_id,
+ &input.dst_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params2.type)
+ dst_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params2.type)
+ dst_name = strdup(loc_params2.loc_data.loc_by_name.name);
+
+ /* if the object, to be moved is open locally, then update its
+ link information */
+ if(!copy_flag && 0 == strcmp(src_name, ".")) {
+ char *link_name = NULL;
+
+ /* generate the entire path of the new link */
+ {
+ size_t obj_name_len = HDstrlen(dst_obj->obj_name);
+ size_t name_len = HDstrlen(loc_params2.loc_data.loc_by_name.name);
+
+ if (NULL == (link_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate");
+ HDmemcpy(link_name, dst_obj->obj_name, obj_name_len);
+ HDmemcpy(link_name+obj_name_len, loc_params2.loc_data.loc_by_name.name, name_len);
+ link_name[obj_name_len+name_len] = '\0';
+ }
+ //H5VL_iod_update_link(dst_obj, loc_params2, link_name);
+ free(link_name);
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.coh = src_obj->file->remote_file.coh;
+ input.copy_flag = copy_flag;
+ input.src_loc_name = src_name;
+ input.dst_loc_name = dst_name;
+ input.lcpl_id = lcpl_id;
+ input.lapl_id = lapl_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = src_obj->file->md_integrity_scope;
+
+ status = (herr_t *)malloc(sizeof(herr_t));
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_MOVE_ID, HG_LINK_MOVE, dst_obj, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input,
+ status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link move");
+
+done:
+ if(src_name)
+ free(src_name);
+ if(dst_name)
+ free(dst_name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_link_move() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_link_iterate
+ *
+ * Purpose: Iterates through links in a group
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t H5VL_iod_link_iterate(void UNUSED *_obj, H5VL_loc_params_t UNUSED loc_params,
+ hbool_t UNUSED recursive,
+ H5_index_t UNUSED idx_type, H5_iter_order_t UNUSED order,
+ hsize_t UNUSED *idx,
+ H5L_iterate_t UNUSED op, void UNUSED *op_data,
+ hid_t UNUSED dxpl_id, void UNUSED **req)
+{
+ //H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ //herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_link_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_link_get
+ *
+ * Purpose: Gets certain data about a link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_link_get(void *_obj, H5VL_loc_params_t loc_params, H5VL_link_get_t get_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ H5P_genplist_t *plist = NULL;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ switch (get_type) {
+ /* H5Lexists */
+ case H5VL_LINK_EXISTS:
+ {
+ link_op_in_t input;
+ htri_t *ret = va_arg (arguments, htri_t *);
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.trans_num = 0;
+ input.path = loc_name;
+
+#if H5VL_IOD_DEBUG
+ printf("Link Exists axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_EXISTS_ID, HG_LINK_EXISTS,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, ret, ret, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link exists");
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Lget_info/H5Lget_info_by_idx */
+ case H5VL_LINK_GET_INFO:
+ {
+ H5L_ff_info_t *linfo = va_arg (arguments, H5L_ff_info_t *);
+ link_op_in_t input;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.trans_num = 0;
+ input.path = loc_name;
+
+#if H5VL_IOD_DEBUG
+ printf("Link get info axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_GET_INFO_ID, HG_LINK_GET_INFO,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, linfo, linfo, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link get_info");
+
+ if(loc_name)
+ HDfree(loc_name);
+
+ break;
+ }
+ /* H5Lget_val/H5Lget_val_by_idx */
+ case H5VL_LINK_GET_VAL:
+ {
+ void *buf = va_arg (arguments, void *);
+ size_t size = va_arg (arguments, size_t);
+ link_get_val_in_t input;
+ link_get_val_out_t *result;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.length = size;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.path = loc_name;
+
+ if(NULL == (result = (link_get_val_out_t *)malloc
+ (sizeof(link_get_val_out_t)))) {
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate get val return struct");
+ }
+
+ result->value.val_size = input.length;
+ result->value.val = buf;
+
+#if H5VL_IOD_DEBUG
+ printf("Link get val axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_GET_VAL_ID, HG_LINK_GET_VAL, obj, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, result, result, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link get_val");
+
+ if(loc_name)
+ HDfree(loc_name);
+
+ break;
+ }
+ /* H5Lget_name_by_idx */
+ case H5VL_LINK_GET_NAME:
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from link")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_link_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_link_remove
+ *
+ * Purpose: Removes the specified NAME from the group graph and
+ * decrements the link count for the object to which NAME
+ * points. If the link count reaches zero then all file-space
+ * associated with the object will be reclaimed (but if the
+ * object is open, then the reclamation of the file space is
+ * delayed until all handles to the object are closed).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_link_remove(void *_obj, H5VL_loc_params_t loc_params, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ link_op_in_t input;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5P_genplist_t *plist = NULL;
+ int *status = NULL;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.path = loc_name;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Link Remove axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, loc_name, input.loc_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_LINK_REMOVE_ID, HG_LINK_REMOVE, obj, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship link remove");
+
+done:
+ if(loc_name)
+ HDfree(loc_name);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_link_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_obj_open_token
+ *
+ * Purpose: Opens a object inside IOD file using it IOD ID
+ *
+ * Return: Success: object id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5VL_iod_obj_open_token(const void *token, H5TR_t *tr, H5I_type_t *opened_type, void **req)
+{
+ object_token_in_t input;
+ const uint8_t *buf_ptr = (const uint8_t *)token;
+ H5O_type_t obj_type;
+ iod_obj_id_t iod_id, mdkv_id, attrkv_id;
+ H5VL_iod_dset_t *dset = NULL; /* the dataset object that is created and passed to the user */
+ H5VL_iod_dtype_t *dtype = NULL; /* the datatype object that is created and passed to the user */
+ H5VL_iod_group_t *grp = NULL; /* the group object that is created and passed to the user */
+ H5VL_iod_map_t *map = NULL; /* the map object that is created and passed to the user */
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDmemcpy(&iod_id, buf_ptr, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(&mdkv_id, buf_ptr, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(&attrkv_id, buf_ptr, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(&obj_type, buf_ptr, sizeof(H5O_type_t));
+ buf_ptr += sizeof(H5O_type_t);
+
+ switch(obj_type) {
+ case H5O_TYPE_DATASET:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_iod_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dset->remote_dset.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dset->remote_dset.iod_id = iod_id;
+ dset->remote_dset.mdkv_id = mdkv_id;
+ dset->remote_dset.attrkv_id = attrkv_id;
+
+ dset->dapl_id = H5Pcopy(H5P_DATASET_ACCESS_DEFAULT);
+ dset->remote_dset.dcpl_id = H5Pcopy(H5P_DATASET_CREATE_DEFAULT);
+
+ /* decode dtype */
+ {
+ H5T_t *dt = NULL;
+ size_t dt_size;
+
+ HDmemcpy(&dt_size, buf_ptr, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ /* Create datatype by decoding buffer */
+ if(NULL == (dt = H5T_decode((const unsigned char *)buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object");
+ /* Register the type */
+ if((dset->remote_dset.type_id = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register data type");
+ buf_ptr += dt_size;
+ }
+
+ /* decode dspace */
+ {
+ H5S_t *ds;
+ size_t space_size;
+
+ HDmemcpy(&space_size, buf_ptr, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if((ds = H5S_decode((const unsigned char *)buf_ptr)) == NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode object");
+ /* Register the type */
+ if((dset->remote_dset.space_id = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTREGISTER, NULL, "unable to register dataspace");
+ buf_ptr += space_size;
+ }
+
+ input.coh = tr->file->remote_file.coh;
+ input.iod_id = iod_id;
+ input.trans_num = tr->trans_num;
+
+ /* set common object parameters */
+ dset->common.obj_type = H5I_DATASET;
+ dset->common.file = tr->file;
+ dset->common.file->nopen_objs ++;
+ dset->common.obj_name = NULL;
+
+#if H5VL_IOD_DEBUG
+ printf("Dataset open by token %"PRIu64": ID %"PRIu64"\n",
+ g_axe_id, input.iod_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_OPEN_BY_TOKEN_ID, HG_OBJECT_OPEN_BY_TOKEN,
+ (H5VL_iod_object_t *)dset, 1, 0, NULL,
+ (H5VL_iod_req_info_t *)tr, &input,
+ &dset->remote_dset.iod_oh, dset, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship dataset open_by_token");
+
+ ret_value = (void *)dset;
+ *opened_type = H5I_DATASET;
+ break;
+ case H5O_TYPE_NAMED_DATATYPE:
+ /* allocate the datatype object that is returned to the user */
+ if(NULL == (dtype = H5FL_CALLOC(H5VL_iod_dtype_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dtype->remote_dtype.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ dtype->remote_dtype.iod_id = iod_id;
+ dtype->remote_dtype.mdkv_id = mdkv_id;
+ dtype->remote_dtype.attrkv_id = attrkv_id;
+
+ dtype->tapl_id = H5Pcopy(H5P_DATATYPE_ACCESS_DEFAULT);
+ dtype->remote_dtype.tcpl_id = H5Pcopy(H5P_DATATYPE_CREATE_DEFAULT);
+
+ /* decode dtype */
+ {
+ H5T_t *dt = NULL;
+ size_t dt_size;
+
+ HDmemcpy(&dt_size, buf_ptr, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ /* Create datatype by decoding buffer */
+ if(NULL == (dt = H5T_decode((const unsigned char *)buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object");
+ /* Register the type */
+ if((dtype->remote_dtype.type_id = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register data type");
+ buf_ptr += dt_size;
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.iod_id = iod_id;
+ input.trans_num = tr->trans_num;
+
+ /* set common object parameters */
+ dtype->common.obj_type = H5I_DATATYPE;
+ dtype->common.file = tr->file;
+ dtype->common.file->nopen_objs ++;
+ dtype->common.obj_name = NULL;
+
+#if H5VL_IOD_DEBUG
+ printf("Named Datatype open by token %"PRIu64": ID %"PRIu64"\n",
+ g_axe_id, input.iod_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_OPEN_BY_TOKEN_ID, HG_OBJECT_OPEN_BY_TOKEN,
+ (H5VL_iod_object_t *)dtype, 1, 0, NULL,
+ (H5VL_iod_req_info_t *)tr, &input,
+ &dtype->remote_dtype.iod_oh, dtype, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship datatype open_by_token");
+
+ ret_value = (void *)dtype;
+ *opened_type = H5I_DATATYPE;
+ break;
+ case H5O_TYPE_GROUP:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (grp = H5FL_CALLOC(H5VL_iod_group_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ grp->remote_group.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ grp->remote_group.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ grp->remote_group.iod_id = iod_id;
+ grp->remote_group.mdkv_id = mdkv_id;
+ grp->remote_group.attrkv_id = attrkv_id;
+
+ grp->remote_group.gcpl_id = H5Pcopy(H5P_GROUP_CREATE_DEFAULT);
+ grp->gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.iod_id = iod_id;
+ input.trans_num = tr->trans_num;
+
+ /* set common object parameters */
+ grp->common.obj_type = H5I_GROUP;
+ grp->common.file = tr->file;
+ grp->common.file->nopen_objs ++;
+ grp->common.obj_name = NULL;
+
+#if H5VL_IOD_DEBUG
+ printf("Group open by token %"PRIu64": ID %"PRIu64"\n",
+ g_axe_id, input.iod_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_OPEN_BY_TOKEN_ID, HG_OBJECT_OPEN_BY_TOKEN,
+ (H5VL_iod_object_t *)grp, 1, 0, NULL,
+ (H5VL_iod_req_info_t *)tr, &input,
+ &grp->remote_group.iod_oh, grp, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship group open_by_token");
+
+ ret_value = (void *)grp;
+ *opened_type = H5I_GROUP;
+ break;
+ case H5O_TYPE_MAP:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_iod_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ map->remote_map.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_id = iod_id;
+ map->remote_map.mdkv_id = mdkv_id;
+ map->remote_map.attrkv_id = attrkv_id;
+
+ map->remote_map.mcpl_id = H5Pcopy(H5P_MAP_CREATE_DEFAULT);
+ map->mapl_id = H5Pcopy(H5P_MAP_ACCESS_DEFAULT);
+
+ /* decode key_type */
+ {
+ H5T_t *dt = NULL;
+ size_t dt_size;
+
+ HDmemcpy(&dt_size, buf_ptr, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ /* Create datatype by decoding buffer */
+ if(NULL == (dt = H5T_decode((const unsigned char *)buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object");
+ /* Register the type */
+ if((map->remote_map.keytype_id = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register data type");
+ buf_ptr += dt_size;
+ }
+ /* decode val_type */
+ {
+ H5T_t *dt = NULL;
+ size_t dt_size;
+
+ HDmemcpy(&dt_size, buf_ptr, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ /* Create datatype by decoding buffer */
+ if(NULL == (dt = H5T_decode((const unsigned char *)buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object");
+ /* Register the type */
+ if((map->remote_map.valtype_id = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, "unable to register data type");
+ buf_ptr += dt_size;
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.iod_id = iod_id;
+ input.trans_num = tr->trans_num;
+
+ /* set common object parameters */
+ map->common.obj_type = H5I_MAP;
+ map->common.file = tr->file;
+ map->common.file->nopen_objs ++;
+ map->common.obj_name = NULL;
+
+#if H5VL_IOD_DEBUG
+ printf("Map open by token %"PRIu64": ID %"PRIu64"\n",
+ g_axe_id, input.iod_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_OPEN_BY_TOKEN_ID, HG_OBJECT_OPEN_BY_TOKEN,
+ (H5VL_iod_object_t *)map, 1, 0, NULL,
+ (H5VL_iod_req_info_t *)tr, &input,
+ &map->remote_map, map, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship map open");
+
+ ret_value = (void *)map;
+ *opened_type = H5I_MAP;
+ break;
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "not a valid file object (dataset, map, group, or datatype)");
+ }
+
+done:
+ if(NULL == ret_value) {
+ switch(obj_type) {
+ case H5O_TYPE_DATASET:
+ if(dset->common.obj_name) {
+ HDfree(dset->common.obj_name);
+ dset->common.obj_name = NULL;
+ }
+ if(dset->common.comment) {
+ HDfree(dset->common.comment);
+ dset->common.comment = NULL;
+ }
+ if(dset->remote_dset.type_id != FAIL && H5I_dec_ref(dset->remote_dset.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dset->remote_dset.space_id != FAIL && H5I_dec_ref(dset->remote_dset.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(dset->remote_dset.dcpl_id != FAIL && H5I_dec_ref(dset->remote_dset.dcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset)
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ break;
+ case H5O_TYPE_NAMED_DATATYPE:
+ /* free dtype components */
+ if(dtype->common.obj_name) {
+ HDfree(dtype->common.obj_name);
+ dtype->common.obj_name = NULL;
+ }
+ if(dtype->common.comment) {
+ HDfree(dtype->common.comment);
+ dtype->common.comment = NULL;
+ }
+ if(dtype->remote_dtype.tcpl_id != FAIL && H5I_dec_ref(dtype->remote_dtype.tcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->tapl_id != FAIL && H5I_dec_ref(dtype->tapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->remote_dtype.type_id != FAIL && H5I_dec_ref(dtype->remote_dtype.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dtype)
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ break;
+ case H5O_TYPE_GROUP:
+ if(grp->common.obj_name) {
+ HDfree(grp->common.obj_name);
+ grp->common.obj_name = NULL;
+ }
+ if(grp->common.comment) {
+ HDfree(grp->common.comment);
+ grp->common.comment = NULL;
+ }
+ if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != FAIL &&
+ H5I_dec_ref(grp->remote_group.gcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp)
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ break;
+ case H5O_TYPE_MAP:
+ /* free map components */
+ if(map->common.obj_name) {
+ HDfree(map->common.obj_name);
+ map->common.obj_name = NULL;
+ }
+ if(map->common.comment) {
+ HDfree(map->common.comment);
+ map->common.comment = NULL;
+ }
+ if(map->remote_map.keytype_id != FAIL && H5I_dec_ref(map->remote_map.keytype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map->remote_map.valtype_id != FAIL && H5I_dec_ref(map->remote_map.valtype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map)
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ break;
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "not a valid object type");
+ } /* end switch */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}/* end H5VL_iod_obj_open_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_object_open
+ *
+ * Purpose: Opens a object inside IOD file.
+ *
+ * Return: Success: object id.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * November, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_iod_object_open(void *_obj, H5VL_loc_params_t loc_params,
+ H5I_type_t *opened_type, hid_t dxpl_id, void UNUSED **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to open the group */
+ H5P_genplist_t *plist = NULL;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ char *loc_name = NULL;
+ object_op_in_t input;
+ H5VL_iod_remote_object_t remote_obj; /* generic remote object structure */
+ H5VL_iod_dset_t *dset = NULL; /* the dataset object that is created and passed to the user */
+ H5VL_iod_dtype_t *dtype = NULL; /* the datatype object that is created and passed to the user */
+ H5VL_iod_group_t *grp = NULL; /* the group object that is created and passed to the user */
+ H5VL_iod_map_t *map = NULL; /* the map object that is created and passed to the user */
+ H5VL_iod_request_t **parent_reqs = NULL;
+ void *ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, &input.loc_mdkv_id, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == input.loc_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &input.loc_id, &input.loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_name = loc_name;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ /* H5Oopen has to be synchronous */
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_OPEN_ID, HG_OBJECT_OPEN,
+ obj, 1, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input,
+ &remote_obj, &remote_obj, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship object open");
+
+ *opened_type = remote_obj.obj_type;
+
+ if(loc_name)
+ HDfree(loc_name);
+
+ switch(remote_obj.obj_type) {
+ case H5I_DATASET:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_iod_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dset->remote_dset.iod_oh.rd_oh.cookie = remote_obj.iod_oh.rd_oh.cookie;
+ dset->remote_dset.iod_oh.wr_oh.cookie = remote_obj.iod_oh.wr_oh.cookie;
+ dset->remote_dset.iod_id = remote_obj.iod_id;
+ dset->remote_dset.mdkv_id = remote_obj.mdkv_id;
+ dset->remote_dset.attrkv_id = remote_obj.attrkv_id;
+ dset->remote_dset.dcpl_id = remote_obj.cpl_id;
+ dset->remote_dset.type_id = remote_obj.id1;
+ dset->remote_dset.space_id = remote_obj.id2;
+
+ if(dset->remote_dset.dcpl_id == H5P_DEFAULT){
+ dset->remote_dset.dcpl_id = H5Pcopy(H5P_DATASET_CREATE_DEFAULT);
+ }
+
+ HDassert(dset->remote_dset.dcpl_id);
+ HDassert(dset->remote_dset.type_id);
+ HDassert(dset->remote_dset.space_id);
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(loc_params.loc_data.loc_by_name.name);
+
+ if (NULL == (dset->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dset->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dset->common.obj_name+obj_name_len,
+ loc_params.loc_data.loc_by_name.name, name_len);
+ dset->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((dset->dapl_id = H5Pcopy(H5P_DATASET_CREATE_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+
+ /* set common object parameters */
+ dset->common.obj_type = H5I_DATASET;
+ dset->common.file = obj->file;
+ dset->common.file->nopen_objs ++;
+
+ ret_value = (void *)dset;
+ break;
+ case H5I_DATATYPE:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (dtype = H5FL_CALLOC(H5VL_iod_dtype_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ dtype->remote_dtype.iod_oh.rd_oh.cookie = remote_obj.iod_oh.rd_oh.cookie;
+ dtype->remote_dtype.iod_oh.wr_oh.cookie = remote_obj.iod_oh.wr_oh.cookie;
+ dtype->remote_dtype.iod_id = remote_obj.iod_id;
+ dtype->remote_dtype.mdkv_id = remote_obj.mdkv_id;
+ dtype->remote_dtype.attrkv_id = remote_obj.attrkv_id;
+ dtype->remote_dtype.tcpl_id = remote_obj.cpl_id;
+ dtype->remote_dtype.type_id = remote_obj.id1;
+
+ if(dtype->remote_dtype.tcpl_id == H5P_DEFAULT){
+ dtype->remote_dtype.tcpl_id = H5Pcopy(H5P_DATATYPE_CREATE_DEFAULT);
+ }
+
+ HDassert(dtype->remote_dtype.tcpl_id);
+ HDassert(dtype->remote_dtype.type_id);
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(loc_params.loc_data.loc_by_name.name);
+
+ if (NULL == (dtype->common.obj_name = (char *)HDmalloc
+ (obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(dtype->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(dtype->common.obj_name+obj_name_len,
+ loc_params.loc_data.loc_by_name.name, name_len);
+ dtype->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((dtype->tapl_id = H5Pcopy(H5P_DATATYPE_CREATE_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+
+ /* set common object parameters */
+ dtype->common.obj_type = H5I_DATATYPE;
+ dtype->common.file = obj->file;
+ dtype->common.file->nopen_objs ++;
+
+ ret_value = (void *)dtype;
+ break;
+ case H5I_GROUP:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (grp = H5FL_CALLOC(H5VL_iod_group_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ grp->remote_group.iod_oh.rd_oh.cookie = remote_obj.iod_oh.rd_oh.cookie;
+ grp->remote_group.iod_oh.wr_oh.cookie = remote_obj.iod_oh.wr_oh.cookie;
+ grp->remote_group.iod_id = remote_obj.iod_id;
+ grp->remote_group.mdkv_id = remote_obj.mdkv_id;
+ grp->remote_group.attrkv_id = remote_obj.attrkv_id;
+ grp->remote_group.gcpl_id = remote_obj.cpl_id;
+
+ if(grp->remote_group.gcpl_id == H5P_DEFAULT){
+ grp->remote_group.gcpl_id = H5Pcopy(H5P_GROUP_CREATE_DEFAULT);
+ }
+
+ HDassert(grp->remote_group.gcpl_id);
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(loc_params.loc_data.loc_by_name.name);
+
+ if (NULL == (grp->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(grp->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(grp->common.obj_name+obj_name_len,
+ loc_params.loc_data.loc_by_name.name, name_len);
+ grp->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((grp->gapl_id = H5Pcopy(H5P_GROUP_CREATE_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy gapl");
+
+ /* set common object parameters */
+ grp->common.obj_type = H5I_GROUP;
+ grp->common.file = obj->file;
+ grp->common.file->nopen_objs ++;
+
+ ret_value = (void *)grp;
+ break;
+ case H5I_MAP:
+ /* allocate the dataset object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_iod_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ map->remote_map.iod_oh.rd_oh.cookie = remote_obj.iod_oh.rd_oh.cookie;
+ map->remote_map.iod_oh.wr_oh.cookie = remote_obj.iod_oh.wr_oh.cookie;
+ map->remote_map.iod_id = remote_obj.iod_id;
+ map->remote_map.mdkv_id = remote_obj.mdkv_id;
+ map->remote_map.attrkv_id = remote_obj.attrkv_id;
+ map->remote_map.mcpl_id = remote_obj.cpl_id;
+ map->remote_map.keytype_id = remote_obj.id1;
+ map->remote_map.valtype_id = remote_obj.id2;
+
+ if(map->remote_map.mcpl_id == H5P_DEFAULT){
+ map->remote_map.mcpl_id = H5Pcopy(H5P_MAP_CREATE_DEFAULT);
+ }
+
+ /* setup the local dataset struct */
+ /* store the entire path of the dataset locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(loc_params.loc_data.loc_by_name.name);
+
+ if (NULL == (map->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(map->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(map->common.obj_name+obj_name_len,
+ loc_params.loc_data.loc_by_name.name, name_len);
+ map->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ if((map->mapl_id = H5Pcopy(H5P_MAP_ACCESS_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy mapl");
+
+ /* set common object parameters */
+ map->common.obj_type = H5I_MAP;
+ map->common.file = obj->file;
+ map->common.file->nopen_objs ++;
+
+ ret_value = (void *)map;
+ break;
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_VIEW:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, NULL, "not a valid file object (dataset, map, group, or datatype)")
+ break;
+ }
+
+done:
+ if(NULL == ret_value) {
+ switch(remote_obj.obj_type) {
+ case H5I_DATASET:
+ if(dset->common.obj_name) {
+ HDfree(dset->common.obj_name);
+ dset->common.obj_name = NULL;
+ }
+ if(dset->common.comment) {
+ HDfree(dset->common.comment);
+ dset->common.comment = NULL;
+ }
+ if(dset->remote_dset.type_id != FAIL && H5I_dec_ref(dset->remote_dset.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dset->remote_dset.space_id != FAIL && H5I_dec_ref(dset->remote_dset.space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dspace");
+ if(dset->remote_dset.dcpl_id != FAIL && H5I_dec_ref(dset->remote_dset.dcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dset)
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ break;
+ case H5I_DATATYPE:
+ /* free dtype components */
+ if(dtype->common.obj_name) {
+ HDfree(dtype->common.obj_name);
+ dtype->common.obj_name = NULL;
+ }
+ if(dtype->common.comment) {
+ HDfree(dtype->common.comment);
+ dtype->common.comment = NULL;
+ }
+ if(dtype->remote_dtype.tcpl_id != FAIL && H5I_dec_ref(dtype->remote_dtype.tcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->tapl_id != FAIL && H5I_dec_ref(dtype->tapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(dtype->remote_dtype.type_id != FAIL && H5I_dec_ref(dtype->remote_dtype.type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(dtype)
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ break;
+ case H5I_GROUP:
+ if(grp->common.obj_name) {
+ HDfree(grp->common.obj_name);
+ grp->common.obj_name = NULL;
+ }
+ if(grp->common.comment) {
+ HDfree(grp->common.comment);
+ grp->common.comment = NULL;
+ }
+ if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != FAIL &&
+ H5I_dec_ref(grp->remote_group.gcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close plist");
+ if(grp)
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ break;
+ case H5I_MAP:
+ /* free map components */
+ if(map->common.obj_name) {
+ HDfree(map->common.obj_name);
+ map->common.obj_name = NULL;
+ }
+ if(map->common.comment) {
+ HDfree(map->common.comment);
+ map->common.comment = NULL;
+ }
+ if(map->remote_map.keytype_id != FAIL && H5I_dec_ref(map->remote_map.keytype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map->remote_map.valtype_id != FAIL && H5I_dec_ref(map->remote_map.valtype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map)
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ break;
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_VIEW:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "not a valid object type");
+ } /* end switch */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_object_open */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_object_copy
+ *
+ * Purpose: Copys a object through the IOD plugin.
+ *
+ * Return: Success: postive.
+ * Failure: NULL
+ *
+ * Programmer: Mohamad Chaarawi
+ * November, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_object_copy(void *_src_obj, H5VL_loc_params_t UNUSED loc_params1, const char *src_name,
+ void *_dst_obj, H5VL_loc_params_t UNUSED loc_params2, const char *dst_name,
+ hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_iod_object_t *src_obj = (H5VL_iod_object_t *)_src_obj;
+ H5VL_iod_object_t *dst_obj = (H5VL_iod_object_t *)_dst_obj;
+ object_copy_in_t input;
+ int *status = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5P_genplist_t *plist = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 3)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(src_obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(src_obj, &input.src_loc_id, &input.src_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(dst_obj, NULL, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(dst_obj, &input.dst_loc_id, &input.dst_loc_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* set the input structure for the HG encode routine */
+ input.coh = src_obj->file->remote_file.coh;
+ input.src_loc_name = src_name;
+ input.dst_loc_name = dst_name;
+ input.lcpl_id = lcpl_id;
+ input.ocpypl_id = ocpypl_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = src_obj->file->md_integrity_scope;
+
+ status = (herr_t *)malloc(sizeof(herr_t));
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_COPY_ID, HG_OBJECT_COPY,
+ (H5VL_iod_object_t *)dst_obj, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship object copy");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_object_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_object_visit
+ *
+ * Purpose: Iterates through all objects linked to an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * November, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t H5VL_iod_object_visit(void UNUSED *_obj, H5VL_loc_params_t UNUSED loc_params,
+ H5_index_t UNUSED idx_type,
+ H5_iter_order_t UNUSED order, H5O_iterate_t UNUSED op,
+ void UNUSED *op_data,
+ hid_t UNUSED dxpl_id, void UNUSED **req)
+{
+ //H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ //herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_object_visit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_object_misc
+ *
+ * Purpose: Perform a plugin specific operation for an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * November, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_object_misc(void *_obj, H5VL_loc_params_t loc_params, H5VL_object_misc_t misc_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ iod_obj_id_t iod_id, mdkv_id, attrkv_id;
+ iod_handles_t iod_oh;
+ int *status = NULL;
+ size_t num_parents = 0;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5P_genplist_t *plist = NULL;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, &mdkv_id, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, &mdkv_id, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ switch (misc_type) {
+ /* H5Arename/rename_by_name */
+ case H5VL_ATTR_RENAME:
+ {
+ const char *old_name = va_arg (arguments, const char *);
+ const char *new_name = va_arg (arguments, const char *);
+ attr_rename_in_t input;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.old_attr_name = old_name;
+ input.new_attr_name = new_name;
+ input.loc_id = iod_id;
+ input.loc_attrkv_id = attrkv_id;
+ input.loc_oh = iod_oh;
+ input.path = loc_name;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Attribute Rename %s to %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ old_name, new_name, input.loc_id, g_axe_id);
+#endif
+
+ status = (herr_t *)malloc(sizeof(herr_t));
+
+ if(H5VL__iod_create_and_forward(H5VL_ATTR_RENAME_ID, HG_ATTR_RENAME,
+ obj, 1, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship attribute rename");
+
+ if(loc_name)
+ HDfree(loc_name);
+
+ break;
+ }
+ /* H5Oset_comment */
+ case H5VL_OBJECT_SET_COMMENT:
+ {
+ const char *comment = va_arg (arguments, char *);
+ object_set_comment_in_t input;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.comment = comment;
+ input.loc_id = iod_id;
+ input.loc_mdkv_id = mdkv_id;
+ input.loc_oh = iod_oh;
+ input.path = loc_name;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+ status = (herr_t *)malloc(sizeof(herr_t));
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_SET_COMMENT_ID, HG_OBJECT_SET_COMMENT,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship object set_comment");
+
+ /* store the comment locally if the object is open */
+ if(loc_params.type == H5VL_OBJECT_BY_SELF)
+ obj->comment = HDstrdup(comment);
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Oincr_refcount / H5Odecr_refcount */
+ case H5VL_OBJECT_CHANGE_REF_COUNT:
+ {
+ //int update_ref = va_arg (arguments, int);
+ }
+ case H5VL_REF_CREATE:
+ {
+ /*
+ void *ref = va_arg (arguments, void *);
+ const char *name = va_arg (arguments, char *);
+ H5R_type_t ref_type = va_arg (arguments, H5R_type_t);
+ hid_t space_id = va_arg (arguments, hid_t);
+ size_t ref_size = 0;
+
+ if(ref_type == H5R_DATASET_REGION)
+ ref_size = sizeof(hdset_reg_ref_t);
+ else if (ref_type == H5R_OBJECT)
+ ref_size = sizeof(hobj_ref_t);
+ */
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_object_misc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_object_get
+ *
+ * Purpose: Gets certain data about a file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Mohamad Chaarawi
+ * November, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_object_get(void *_obj, H5VL_loc_params_t loc_params, H5VL_object_get_t get_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ size_t num_parents = 0;
+ hid_t rcxt_id;
+ H5RC_t *rc = NULL;
+ H5P_genplist_t *plist = NULL;
+ iod_obj_id_t iod_id, mdkv_id, attrkv_id;
+ iod_handles_t iod_oh;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ char *loc_name = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, &mdkv_id, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, &mdkv_id, &attrkv_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to resolve current location group info");
+ }
+
+ switch (get_type) {
+ /* H5Oexists_by_name */
+ case H5VL_OBJECT_EXISTS:
+ {
+ htri_t *ret = va_arg (arguments, htri_t *);
+ object_op_in_t input;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_mdkv_id = mdkv_id;
+ input.loc_oh = iod_oh;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.loc_name = loc_name;
+
+#if H5VL_IOD_DEBUG
+ printf("Object Exists axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, input.loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_EXISTS_ID, HG_OBJECT_EXISTS,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, ret, ret, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship object exists");
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Oget_comment / H5Oget_comment_by_name */
+ case H5VL_OBJECT_GET_COMMENT:
+ {
+ char *comment = va_arg (arguments, char *);
+ size_t size = va_arg (arguments, size_t);
+ ssize_t *ret = va_arg (arguments, ssize_t *);
+ object_get_comment_in_t input;
+ object_get_comment_out_t *result = NULL;
+ size_t len;
+
+ /* If the comment is present locally, get it and return */
+ if(loc_params.type == H5VL_OBJECT_BY_SELF && obj->comment) {
+ len = HDstrlen(obj->comment);
+
+ if(comment) {
+ HDstrncpy(comment, obj->comment, MIN(len + 1,size));
+ if(len >= size)
+ comment[size-1]='\0';
+ } /* end if */
+
+ /* Set the return value for the API call */
+ *ret = (ssize_t)len;
+ break;
+ }
+
+ /* Otherwise Go to the server */
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = HDstrdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = HDstrdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.loc_mdkv_id = mdkv_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.path = loc_name;
+ if(comment)
+ input.length = size;
+ else
+ input.length = 0;
+
+ if(NULL == (result = (object_get_comment_out_t *)malloc
+ (sizeof(object_get_comment_out_t)))) {
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate get comment return struct");
+ }
+
+ result->name.size = input.length;
+ result->name.value_size = ret;
+ result->name.value = comment;
+
+#if H5VL_IOD_DEBUG
+ printf("Object Get Comment axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_GET_COMMENT_ID, HG_OBJECT_GET_COMMENT,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, result, result, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship object get_comment");
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx */
+ case H5VL_OBJECT_GET_INFO:
+ {
+ H5O_ff_info_t *oinfo = va_arg (arguments, H5O_ff_info_t *);
+ object_op_in_t input;
+
+ if(H5VL_OBJECT_BY_SELF == loc_params.type)
+ loc_name = strdup(".");
+ else if(H5VL_OBJECT_BY_NAME == loc_params.type)
+ loc_name = strdup(loc_params.loc_data.loc_by_name.name);
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.loc_mdkv_id = mdkv_id;
+ input.loc_attrkv_id = attrkv_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.loc_name = loc_name;
+
+#if H5VL_IOD_DEBUG
+ printf("Object get_info axe %"PRIu64": %s ID %"PRIu64"\n",
+ g_axe_id, input.loc_name, input.loc_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_OBJECT_GET_INFO_ID, HG_OBJECT_GET_INFO,
+ obj, 0, num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, oinfo, oinfo, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship object get_info");
+
+ if(loc_name)
+ HDfree(loc_name);
+ break;
+ }
+ /* H5Rget_region */
+ case H5VL_REF_GET_REGION:
+ {
+ //hid_t *ret = va_arg (arguments, hid_t *);
+ //H5R_type_t ref_type = va_arg (arguments, H5R_type_t);
+ //void *ref = va_arg (arguments, void *);
+ //H5S_t *space = NULL; /* Dataspace object */
+ }
+ /* H5Rget_obj_type2 */
+ case H5VL_REF_GET_TYPE:
+ {
+ //H5O_type_t *obj_type = va_arg (arguments, H5O_type_t *);
+ //H5R_type_t ref_type = va_arg (arguments, H5R_type_t);
+ //const void *ref = va_arg (arguments, const void *);
+ }
+ /* H5Rget_name */
+ case H5VL_REF_GET_NAME:
+ {
+ //ssize_t *ret = va_arg (arguments, ssize_t *);
+ //char *name = va_arg (arguments, char *);
+ //size_t size = va_arg (arguments, size_t);
+ //H5R_type_t ref_type = va_arg (arguments, H5R_type_t);
+ //void *ref = va_arg (arguments, void *);
+ }
+ default:
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object")
+ }
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_object_get() */
+
+void *
+H5VL_iod_map_create(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t keytype, hid_t valtype, hid_t lcpl_id, hid_t mcpl_id,
+ hid_t mapl_id, hid_t trans_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the group */
+ H5VL_iod_map_t *map = NULL; /* the map object that is created and passed to the user */
+ map_create_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ size_t num_parents = 0;
+ H5TR_t *tr = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the map object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_iod_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ map->remote_map.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_id = IOD_OBJ_INVALID;
+ map->remote_map.mcpl_id = -1;
+
+ /* Generate IOD IDs for the map to be created */
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.map_id);
+ map->remote_map.iod_id = input.map_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.mdkv_id);
+ map->remote_map.mdkv_id = input.mdkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ H5VL_iod_gen_obj_id(obj->file->my_rank, obj->file->num_procs,
+ obj->file->remote_file.kv_oid_index,
+ IOD_OBJ_KV, &input.attrkv_id);
+ map->remote_map.attrkv_id = input.attrkv_id;
+ /* increment the index of KV objects created on the container */
+ obj->file->remote_file.kv_oid_index ++;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.keytype_id = keytype;
+ input.valtype_id = valtype;
+ input.mcpl_id = mcpl_id;
+ input.mapl_id = mapl_id;
+ input.lcpl_id = lcpl_id;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Map Create %s, IOD ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.map_id, g_axe_id);
+#endif
+
+ /* setup the local map struct */
+ /* store the entire path of the map locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (map->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(map->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(map->common.obj_name+obj_name_len, name, name_len);
+ map->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* copy property lists */
+ if((map->remote_map.mcpl_id = H5Pcopy(mcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy mcpl");
+ if((map->mapl_id = H5Pcopy(mapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy mapl");
+ if((map->remote_map.keytype_id = H5Tcopy(keytype)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dtype");
+ if((map->remote_map.valtype_id = H5Tcopy(valtype)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dtype");
+
+ /* set common object parameters */
+ map->common.obj_type = H5I_MAP;
+ map->common.file = obj->file;
+ map->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_CREATE_ID, HG_MAP_CREATE,
+ (H5VL_iod_object_t *)map, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, &map->remote_map, map, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship map create");
+
+ ret_value = (void *)map;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free map components */
+ if(map->common.obj_name) {
+ HDfree(map->common.obj_name);
+ map->common.obj_name = NULL;
+ }
+ if(map->common.comment) {
+ HDfree(map->common.comment);
+ map->common.comment = NULL;
+ }
+ if(map->remote_map.keytype_id != FAIL && H5I_dec_ref(map->remote_map.keytype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map->remote_map.valtype_id != FAIL && H5I_dec_ref(map->remote_map.valtype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map)
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_create() */
+
+void *
+H5VL_iod_map_open(void *_obj, H5VL_loc_params_t UNUSED loc_params, const char *name,
+ hid_t mapl_id, hid_t rcxt_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the group */
+ H5VL_iod_map_t *map = NULL; /* the map object that is created and passed to the user */
+ map_open_in_t input;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a READ CONTEXT ID")
+
+ /* allocate parent request array */
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(obj, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to retrieve parent requests");
+
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+
+ /* MSC - If location object not opened yet, wait for it. */
+ if(IOD_OBJ_INVALID == iod_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't wait on HG request");
+ obj->request = NULL;
+ /* retrieve IOD info of location object */
+ if(H5VL_iod_get_loc_info(obj, &iod_id, &iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current location group info");
+ }
+
+ /* allocate the map object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_iod_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate object struct");
+
+ map->remote_map.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ map->remote_map.iod_id = IOD_OBJ_INVALID;
+ map->remote_map.mdkv_id = IOD_OBJ_INVALID;
+ map->remote_map.attrkv_id = IOD_OBJ_INVALID;
+ map->remote_map.keytype_id = -1;
+ map->remote_map.valtype_id = -1;
+
+ /* set the input structure for the HG encode routine */
+ input.coh = obj->file->remote_file.coh;
+ input.loc_id = iod_id;
+ input.loc_oh = iod_oh;
+ input.name = name;
+ input.mapl_id = mapl_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("Map Open %s LOC ID %"PRIu64", axe id %"PRIu64"\n",
+ name, input.loc_id, g_axe_id);
+#endif
+
+ /* setup the local map struct */
+ /* store the entire path of the map locally */
+ if(obj->obj_name) {
+ size_t obj_name_len = HDstrlen(obj->obj_name);
+ size_t name_len = HDstrlen(name);
+
+ if (NULL == (map->common.obj_name = (char *)HDmalloc(obj_name_len + name_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate");
+ HDmemcpy(map->common.obj_name, obj->obj_name, obj_name_len);
+ HDmemcpy(map->common.obj_name+obj_name_len, name, name_len);
+ map->common.obj_name[obj_name_len+name_len] = '\0';
+ }
+
+ /* copy property lists */
+ if((map->mapl_id = H5Pcopy(mapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy mapl");
+
+ /* set common object parameters */
+ map->common.obj_type = H5I_MAP;
+ map->common.file = obj->file;
+ map->common.file->nopen_objs ++;
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_OPEN_ID, HG_MAP_OPEN, (H5VL_iod_object_t *)map, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, &map->remote_map, map, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to create and ship map open");
+
+ ret_value = (void *)map;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or
+ it failed locally, then cleanup and return fail */
+ if(NULL == ret_value) {
+ /* free map components */
+ if(map->common.obj_name) {
+ HDfree(map->common.obj_name);
+ map->common.obj_name = NULL;
+ }
+ if(map->common.comment) {
+ HDfree(map->common.comment);
+ map->common.comment = NULL;
+ }
+ if(map->remote_map.keytype_id != FAIL && H5I_dec_ref(map->remote_map.keytype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map->remote_map.valtype_id != FAIL && H5I_dec_ref(map->remote_map.valtype_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "failed to close dtype");
+ if(map)
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_open() */
+
+herr_t
+H5VL_iod_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,
+ hid_t trans_id, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_set_in_t input;
+ size_t key_size, val_size;
+ int *status = NULL;
+ H5P_genplist_t *plist = NULL;
+ size_t num_parents = 0;
+ H5TR_t *tr = NULL;
+ hg_bulk_t *value_handle = NULL;
+ uint64_t key_cs, value_cs, user_cs;
+ uint32_t raw_cs_scope;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5T_class_t val_type_class;
+ H5VL_iod_map_set_info_t *info = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the dataset that is not present locally, wait */
+ if(-1 == map->remote_map.keytype_id ||
+ -1 == map->remote_map.valtype_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(map->common.file, map->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request");
+ map->common.request = NULL;
+ }
+
+ /* get the key size and checksum from the provided key datatype & buffer */
+ if(H5VL_iod_map_get_size(key_mem_type_id, key, &key_cs, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* get the plist pointer */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ /* get the data integrity scope */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &raw_cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ if(raw_cs_scope) {
+ /* get the value size and checksum from the provided value datatype & buffer */
+ if(H5VL_iod_map_get_size(val_mem_type_id, value, &value_cs,
+ &val_size, &val_type_class) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get value size");
+ }
+ else {
+#if H5VL_IOD_DEBUG
+ printf("NO DATA INTEGRITY CHECKS ON RAW DATA WRITTEN\n");
+#endif
+ /* get the value size and checksum from the provided value datatype & buffer */
+ if(H5VL_iod_map_get_size(val_mem_type_id, value, NULL,
+ &val_size, &val_type_class) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get value size");
+ }
+
+ /* Verify the checksum value if the dxpl contains a user defined checksum */
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_NAME, &user_cs) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum value");
+
+ if((raw_cs_scope & H5_CHECKSUM_MEMORY) && user_cs &&
+ user_cs != value_cs) {
+ fprintf(stderr, "Errrr.. In memory Data corruption. expecting %"PRIu64", got %"PRIu64"\n",
+ user_cs, value_cs);
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "Checksum verification failed");
+ }
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (value_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a bulk data transfer handle");
+
+ /* Register memory */
+ if(H5T_VLEN == val_type_class) {
+ /* if this is a VL type buffer, set the buffer pointer to the
+ actual data (the p pointer) */
+ if(HG_SUCCESS != HG_Bulk_handle_create(((const hvl_t *)value)->p, val_size,
+ HG_BULK_READ_ONLY, value_handle))
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't create Bulk Data Handle");
+ }
+ else {
+ if(HG_SUCCESS != HG_Bulk_handle_create(value, val_size, HG_BULK_READ_ONLY, value_handle))
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't create Bulk Data Handle");
+ }
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)map, (H5VL_iod_req_info_t *)tr,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = map->common.file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.dxpl_id = dxpl_id;
+ input.key_maptype_id = map->remote_map.keytype_id;
+ input.key_memtype_id = key_mem_type_id;
+ input.key.buf_size = key_size;
+ input.key.buf = key;
+ input.val_maptype_id = map->remote_map.valtype_id;
+ input.val_memtype_id = val_mem_type_id;
+ input.val_handle = *value_handle;
+ input.val_checksum = value_cs;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = map->common.file->md_integrity_scope;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("MAP set, value size %zu, axe id %"PRIu64"\n", val_size, g_axe_id);
+#endif
+
+ /* setup info struct for I/O request
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_map_set_info_t *)H5MM_calloc(sizeof(H5VL_iod_map_set_info_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate a request");
+
+ info->status = status;
+ info->value_handle = value_handle;
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_SET_ID, HG_MAP_SET,
+ (H5VL_iod_object_t *)map, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map set");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_set() */
+
+herr_t
+H5VL_iod_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, hid_t rcxt_id, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_get_in_t input;
+ H5P_genplist_t *plist = NULL;
+ map_get_out_t *output = NULL;
+ H5VL_iod_map_io_info_t *info = NULL;
+ size_t key_size, val_size;
+ hg_bulk_t *value_handle = NULL;
+ hg_bulk_t dummy_handle;
+ uint64_t key_cs = 0;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ hbool_t val_is_vl;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the map that is not present locally, wait */
+ if(-1 == map->remote_map.keytype_id ||
+ -1 == map->remote_map.valtype_id) {
+ /* Synchronously wait on the request attached to the map */
+ if(H5VL_iod_request_wait(map->common.file, map->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request");
+ map->common.request = NULL;
+ }
+
+ /* get the key size and checksum from the provided key datatype & buffer */
+ if(H5VL_iod_map_get_size(key_mem_type_id, key, &key_cs, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, 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_iod_map_dtype_info(val_mem_type_id, &val_is_vl, &val_size) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* allocate a bulk data transfer handle */
+ if(NULL == (value_handle = (hg_bulk_t *)H5MM_malloc(sizeof(hg_bulk_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate a buld data transfer handle");
+
+ /* If the val type is not VL, then we know the size and we can
+ create the bulk handle */
+ if(!val_is_vl) {
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(value, val_size,
+ HG_BULK_READWRITE, value_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+ }
+ else {
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(value, (size_t)1,
+ HG_BULK_READWRITE, &dummy_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+ }
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)map, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = map->common.file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.dxpl_id = dxpl_id;
+ input.key_memtype_id = key_mem_type_id;
+ input.key_maptype_id = map->remote_map.keytype_id;
+ input.val_memtype_id = val_mem_type_id;
+ input.val_maptype_id = map->remote_map.valtype_id;
+ input.key.buf_size = key_size;
+ input.key.buf = key;
+ input.val_is_vl = val_is_vl;
+ input.val_size = val_size;
+ input.rcxt_num = rc->c_version;
+ if(!val_is_vl)
+ input.val_handle = *value_handle;
+ else {
+ input.val_handle = dummy_handle;
+ }
+ input.cs_scope = map->common.file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("MAP Get, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ /* get the plist pointer */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+ if(NULL == (output = (map_get_out_t *)H5MM_calloc(sizeof(map_get_out_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate map get output struct");
+
+ /* setup info struct for I/O request.
+ This is to manage the I/O operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_map_io_info_t *)H5MM_calloc(sizeof(H5VL_iod_map_io_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request");
+
+ /* capture the parameters required to submit a get request again
+ if the value type is VL, since the first Get is to retrieve the
+ value size */
+ info->val_ptr = value;
+ info->read_buf = NULL;
+ info->value_handle = value_handle;
+
+ info->val_is_vl = val_is_vl;
+
+ /* store the pointer to the buffer where the checksum needs to be placed */
+ if(H5P_get(plist, H5D_XFER_CHECKSUM_PTR_NAME, &info->val_cs_ptr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum pointer value");
+ /* store the raw data integrity scope */
+ if(H5P_get(plist, H5VL_CS_BITFLAG_NAME, &info->raw_cs_scope) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get checksum pointer value");
+
+ /* The value size expected to be received. If VL data, this will
+ be 0, because the first call would be to get the value size */
+ info->val_size = val_size;
+ info->rcxt_id = rcxt_id;
+ info->key.buf_size = key_size;
+ info->key.buf = key;
+ info->output = output;
+ if(val_is_vl) {
+ if((info->val_mem_type_id = H5Tcopy(val_mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype");
+ if((info->key_mem_type_id = H5Tcopy(key_mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype");
+ if((info->dxpl_id = H5P_copy_plist((H5P_genplist_t *)plist, TRUE)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy dxpl");
+
+ info->peer = PEER;
+ info->map_get_id = H5VL_MAP_GET_ID;
+ }
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_GET_ID, HG_MAP_GET,
+ (H5VL_iod_object_t *)map, 0,
+ num_parents, parent_reqs, (H5VL_iod_req_info_t *)rc,
+ &input, output, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map get");
+
+ if(val_is_vl && (HG_SUCCESS != HG_Bulk_handle_free(dummy_handle))) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "failed to free dummy handle created");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_get() */
+
+herr_t
+H5VL_iod_map_get_types(void *_map, hid_t *key_type_id, hid_t *val_type_id,
+ hid_t UNUSED rcxt_id, void UNUSED **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If there is information needed about the dataset that is not present locally, wait */
+ if(-1 == map->remote_map.keytype_id ||
+ -1 == map->remote_map.valtype_id) {
+ /* Synchronously wait on the request attached to the dataset */
+ if(H5VL_iod_request_wait(map->common.file, map->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request");
+ map->common.request = NULL;
+ }
+
+ if((*key_type_id = H5Tcopy(map->remote_map.keytype_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of map key")
+
+ if((*val_type_id = H5Tcopy(map->remote_map.valtype_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_iod_map_get_types() */
+
+herr_t
+H5VL_iod_map_get_count(void *_map, hsize_t *count, hid_t rcxt_id, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_get_count_in_t input;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID")
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)map, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = map->common.file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = map->common.file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("MAP Get count, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_GET_COUNT_ID, HG_MAP_GET_COUNT,
+ (H5VL_iod_object_t *)map, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input, count, count, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map get_count");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_get_count() */
+
+herr_t
+H5VL_iod_map_exists(void *_map, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, hid_t rcxt_id, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_op_in_t input;
+ size_t key_size;
+ H5RC_t *rc = NULL;
+ size_t num_parents = 0;
+ uint64_t key_cs = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ H5VL_iod_exists_info_t *info = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(H5VL_iod_map_get_size(key_mem_type_id, key, &key_cs, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID")
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)map, (H5VL_iod_req_info_t *)rc,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = map->common.file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.key_maptype_id = map->remote_map.keytype_id;
+ input.key_memtype_id = key_mem_type_id;
+ input.key.buf_size = key_size;
+ input.key.buf = key;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = map->common.file->md_integrity_scope;
+ input.trans_num = 0;
+
+#if H5VL_IOD_DEBUG
+ printf("MAP EXISTS, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ /* setup info struct for exists request.
+ This is to manage the exists operation once the wait is called. */
+ if(NULL == (info = (H5VL_iod_exists_info_t *)H5MM_calloc(sizeof(H5VL_iod_exists_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a request");
+
+ info->user_bool = exists;
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_EXISTS_ID, HG_MAP_EXISTS,
+ (H5VL_iod_object_t *)map, 0,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)rc, &input,
+ &info->server_ret, info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map exists");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_exists() */
+
+herr_t
+H5VL_iod_map_iterate(void UNUSED *map, hid_t UNUSED key_mem_type_id, hid_t UNUSED value_mem_type_id,
+ H5M_iterate_func_t UNUSED callback_func, void UNUSED *context)
+{
+ //herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_map_iterate() */
+
+herr_t
+H5VL_iod_map_delete(void *_map, hid_t key_mem_type_id, const void *key,
+ hid_t trans_id, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_op_in_t input;
+ size_t key_size;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5TR_t *tr = NULL;
+ uint64_t key_cs = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(H5VL_iod_map_get_size(key_mem_type_id, key, &key_cs, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a Transaction ID")
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *) * 2)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests((H5VL_iod_object_t *)map, (H5VL_iod_req_info_t *)tr,
+ parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* Fill input structure */
+ input.coh = map->common.file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.key_maptype_id = map->remote_map.keytype_id;
+ input.key_memtype_id = key_mem_type_id;
+ input.key.buf_size = key_size;
+ input.key.buf = key;
+ input.trans_num = tr->trans_num;
+ input.rcxt_num = tr->c_version;
+ input.cs_scope = map->common.file->md_integrity_scope;
+
+#if H5VL_IOD_DEBUG
+ printf("MAP DELETE, axe id %"PRIu64"\n", g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_DELETE_ID, HG_MAP_DELETE,
+ (H5VL_iod_object_t *)map, 1,
+ num_parents, parent_reqs,
+ (H5VL_iod_req_info_t *)tr, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map delete");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_delete() */
+
+herr_t H5VL_iod_map_close(void *_map, void **req)
+{
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map;
+ map_close_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(map->common.file, map) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(IOD_OH_UNDEFINED == map->remote_map.iod_oh.rd_oh.cookie) {
+ /* Synchronously wait on the request attached to the map */
+ if(H5VL_iod_request_wait(map->common.file, map->common.request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on map request");
+ map->common.request = NULL;
+ }
+
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)map, &num_parents, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num requests");
+
+ if(num_parents) {
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * num_parents)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+ if(H5VL_iod_get_obj_requests((H5VL_iod_object_t *)map, &num_parents,
+ parent_reqs) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get parents requests");
+ }
+
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+
+#if H5VL_IOD_DEBUG
+ printf("Map Close IOD ID %"PRIu64", axe id %"PRIu64"\n", input.iod_id, g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_MAP_CLOSE_ID, HG_MAP_CLOSE,
+ (H5VL_iod_object_t *)map, 1,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map close");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_rc_acquire
+ *
+ * Purpose: Forwards an acquire for a read context to IOD.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_rc_acquire(H5VL_iod_file_t *file, H5RC_t *rc, uint64_t *c_version,
+ hid_t rcapl_id, void **req)
+{
+ rc_acquire_in_t input;
+ H5VL_iod_rc_info_t *rc_info = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* set the input structure for the HG encode routine */
+ input.coh = file->remote_file.coh;
+ input.c_version = *c_version;
+ input.rcapl_id = rcapl_id;
+
+ /* setup the info structure for updating the RC on completion */
+ if(NULL == (rc_info = (H5VL_iod_rc_info_t *)H5MM_calloc(sizeof(H5VL_iod_rc_info_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate RC info struct");
+
+ rc_info->read_cxt = rc;
+ rc_info->c_version_ptr = c_version;
+
+#if H5VL_IOD_DEBUG
+ printf("Read Context Acquire, version %"PRIu64", axe id %"PRIu64"\n",
+ input.c_version, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_RC_ACQUIRE_ID, HG_RC_ACQUIRE,
+ (H5VL_iod_object_t *)file, 0, 0, NULL,
+ NULL, &input, &rc_info->result, rc_info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+ if(NULL != req) {
+ H5VL_iod_request_t *request = (H5VL_iod_request_t *)(*req);
+
+ rc->req_info.request = request;
+ //request->ref_count ++;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_rc_acquire() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_rc_release
+ *
+ * Purpose: Forwards a release on an acquired read context to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_rc_release(H5RC_t *rc, void **req)
+{
+ rc_release_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * (rc->req_info.num_req + 1))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+
+ /* retrieve start request */
+ if(H5VL_iod_get_parent_requests(NULL, (H5VL_iod_req_info_t *)rc, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ if(rc->req_info.num_req) {
+ H5VL_iod_request_t *cur_req = rc->req_info.head;
+ H5VL_iod_request_t *next_req = NULL;
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ while(cur_req) {
+ /* add a dependency if the current request in the list is pending */
+ if(cur_req->state == H5VL_IOD_PENDING) {
+ /* If this call is not asynchronous, wait on a dependent request */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait(rc->file, cur_req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on request");
+ }
+ /* Otherwise, add a dependency */
+ else {
+ parent_reqs[num_parents] = cur_req;
+ cur_req->ref_count ++;
+ num_parents ++;
+ }
+ }
+
+ next_req = cur_req->trans_next;
+
+ /* remove the current request from the linked list */
+ prev = cur_req->trans_prev;
+ next = cur_req->trans_next;
+ if (prev) {
+ if (next) {
+ prev->trans_next = next;
+ next->trans_prev = prev;
+ }
+ else {
+ prev->trans_next = NULL;
+ rc->req_info.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->trans_prev = NULL;
+ rc->req_info.head = next;
+ }
+ else {
+ rc->req_info.head = NULL;
+ rc->req_info.tail = NULL;
+ }
+ }
+
+ cur_req->trans_prev = NULL;
+ cur_req->trans_next = NULL;
+
+ rc->req_info.num_req --;
+
+ H5VL_iod_request_decr_rc(cur_req);
+
+ cur_req = next_req;
+ }
+ HDassert(0 == rc->req_info.num_req);
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.coh = rc->file->remote_file.coh;
+ input.c_version = rc->c_version;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Read Context Release, version %"PRIu64", axe id %"PRIu64"\n",
+ input.c_version, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_RC_RELEASE_ID, HG_RC_RELEASE,
+ (H5VL_iod_object_t *)rc->file, 0,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+ //if(NULL != rc->req_info.request) {
+ //H5VL_iod_request_decr_rc(rc->req_info.request);
+ //}
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_rc_release() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_rc_persist
+ *
+ * Purpose: Forwards an persist on an acquired read context to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_rc_persist(H5RC_t *rc, void **req)
+{
+ rc_persist_in_t input;
+ int *status = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(!(rc->file->flags & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Can't persist a container opened for Read only")
+
+ /* set the input structure for the HG encode routine */
+ input.coh = rc->file->remote_file.coh;
+ input.c_version = rc->c_version;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Read Context Persist, version %"PRIu64", axe id %"PRIu64"\n",
+ input.c_version, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_RC_PERSIST_ID, HG_RC_PERSIST,
+ (H5VL_iod_object_t *)rc->file, 0, 0, NULL,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_rc_persist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_rc_snapshot
+ *
+ * Purpose: Forwards an snapshot on an acquired read context to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_rc_snapshot(H5RC_t *rc, const char *snapshot_name, void **req)
+{
+ rc_snapshot_in_t input;
+ int *status = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* set the input structure for the HG encode routine */
+ input.coh = rc->file->remote_file.coh;
+ input.c_version = rc->c_version;
+ input.snapshot_name = snapshot_name;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Read Context Snapshot, version %"PRIu64", axe id %"PRIu64"\n",
+ input.c_version, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_RC_SNAPSHOT_ID, HG_RC_SNAPSHOT,
+ (H5VL_iod_object_t *)rc->file, 0, 0, NULL,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_rc_snapshot() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_tr_start
+ *
+ * Purpose: Forwards a transaction start call to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_tr_start(H5TR_t *tr, hid_t trspl_id, void **req)
+{
+ tr_start_in_t input;
+ H5VL_iod_tr_info_t *tr_info = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.trans_num = tr->trans_num;
+ input.trspl_id = trspl_id;
+
+#if H5VL_IOD_DEBUG
+ printf("Transaction start, number %"PRIu64", axe id %"PRIu64"\n",
+ input.trans_num, g_axe_id);
+#endif
+
+ /* setup the info structure for updating the transaction on completion */
+ if(NULL == (tr_info = (H5VL_iod_tr_info_t *)H5MM_calloc(sizeof(H5VL_iod_tr_info_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate TR info struct");
+
+ tr_info->tr = tr;
+
+ if(H5VL__iod_create_and_forward(H5VL_TR_START_ID, HG_TR_START,
+ (H5VL_iod_object_t *)tr->file, 0, 0, NULL,
+ NULL, &input, &tr_info->result, tr_info, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+ if(NULL != req) {
+ H5VL_iod_request_t *request = (H5VL_iod_request_t *)(*req);
+
+ tr->req_info.request = request;
+ //request->ref_count ++;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_tr_start() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_tr_finish
+ *
+ * Purpose: Forwards a transaction finish call to IOD.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_tr_finish(H5TR_t *tr, hbool_t acquire, hid_t trfpl_id, void **req)
+{
+ tr_finish_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)H5MM_malloc
+ (sizeof(H5VL_iod_request_t *) * (tr->req_info.num_req + 1))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array of parent reqs");
+
+ /* retrieve start request */
+ if(H5VL_iod_get_parent_requests(NULL, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ if(tr->req_info.num_req) {
+ H5VL_iod_request_t *cur_req = tr->req_info.head;
+ H5VL_iod_request_t *next_req = NULL;
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ while(cur_req) {
+ /* add a dependency if the current request in the list is pending */
+ if(cur_req->state == H5VL_IOD_PENDING) {
+ /* If this call is not asynchronous, wait on a dependent request */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait(tr->file, cur_req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on request");
+ }
+ /* Otherwise, add a dependency */
+ else {
+ parent_reqs[num_parents] = cur_req;
+ cur_req->ref_count ++;
+ num_parents ++;
+ }
+ }
+
+ next_req = cur_req->trans_next;
+
+ /* remove the current request from the linked list */
+ prev = cur_req->trans_prev;
+ next = cur_req->trans_next;
+ if (prev) {
+ if (next) {
+ prev->trans_next = next;
+ next->trans_prev = prev;
+ }
+ else {
+ prev->trans_next = NULL;
+ tr->req_info.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->trans_prev = NULL;
+ tr->req_info.head = next;
+ }
+ else {
+ tr->req_info.head = NULL;
+ tr->req_info.tail = NULL;
+ }
+ }
+
+ cur_req->trans_prev = NULL;
+ cur_req->trans_next = NULL;
+
+ tr->req_info.num_req --;
+
+ H5VL_iod_request_decr_rc(cur_req);
+
+ cur_req = next_req;
+ }
+ HDassert(0 == tr->req_info.num_req);
+ }
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.cs_scope = tr->file->md_integrity_scope;
+ input.trans_num = tr->trans_num;
+ input.trfpl_id = trfpl_id;
+ input.acquire = acquire;
+ input.client_rank = (uint32_t)tr->file->my_rank;
+ input.oidkv_id = (iod_obj_id_t)(tr->file->num_procs * 3);
+ input.kv_oid_index = tr->file->remote_file.kv_oid_index;
+ input.array_oid_index = tr->file->remote_file.array_oid_index;
+ input.blob_oid_index = tr->file->remote_file.blob_oid_index;
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Transaction Finish, %"PRIu64", axe id %"PRIu64"\n",
+ input.trans_num, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_TR_FINISH_ID, HG_TR_FINISH,
+ (H5VL_iod_object_t *)tr->file, 0,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+ //if(NULL != tr->req_info.request) {
+ //H5VL_iod_request_decr_rc(tr->req_info.request);
+ //}
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_tr_finish() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_tr_set_dependency
+ *
+ * Purpose: Forwards a transaction set dependency to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_tr_set_dependency(H5TR_t *tr, uint64_t trans_num, void **req)
+{
+ tr_set_depend_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(NULL, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.child_trans_num = tr->trans_num;
+ input.parent_trans_num = trans_num;
+
+#if H5VL_IOD_DEBUG
+ printf("Transaction Set Dependency, %"PRIu64" on %"PRIu64" axe id %"PRIu64"\n",
+ input.child_trans_num, input.parent_trans_num, g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_TR_SET_DEPEND_ID, HG_TR_SET_DEPEND,
+ (H5VL_iod_object_t *)tr->file, 0,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_tr_set_dependency() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_tr_skip
+ *
+ * Purpose: Forwards a transaction skip to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_tr_skip(H5VL_iod_file_t *file, uint64_t start_trans_num, uint64_t count, void **req)
+{
+ tr_skip_in_t input;
+ int *status = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* set the input structure for the HG encode routine */
+ input.coh = file->remote_file.coh;
+ input.start_trans_num = start_trans_num;
+ input.count = count;
+
+#if H5VL_IOD_DEBUG
+ printf("Transaction Skip, tr %"PRIu64" count %"PRIu64",, axe id %"PRIu64"\n",
+ input.start_trans_num, input.count, g_axe_id);
+#endif
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_TR_SKIP_ID, HG_TR_SKIP,
+ (H5VL_iod_object_t *)file, 0, 0, NULL,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_tr_skip() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_tr_abort
+ *
+ * Purpose: Forwards a transaction abort to IOD
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * September 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_tr_abort(H5TR_t *tr, void **req)
+{
+ tr_abort_in_t input;
+ int *status = NULL;
+ size_t num_parents = 0;
+ H5VL_iod_request_t **parent_reqs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (parent_reqs = (H5VL_iod_request_t **)
+ H5MM_malloc(sizeof(H5VL_iod_request_t *))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate parent req element");
+
+ /* retrieve parent requests */
+ if(H5VL_iod_get_parent_requests(NULL, (H5VL_iod_req_info_t *)tr, parent_reqs, &num_parents) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to retrieve parent requests");
+
+ /* set the input structure for the HG encode routine */
+ input.coh = tr->file->remote_file.coh;
+ input.trans_num = tr->trans_num;
+
+ /* remove all nodes from the transaction linked list */
+ if(tr->req_info.num_req) {
+ H5VL_iod_request_t *cur_req = tr->req_info.head;
+ H5VL_iod_request_t *next_req = NULL;
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+
+ while(cur_req) {
+ next_req = cur_req->trans_next;
+
+ prev = cur_req->trans_prev;
+ next = cur_req->trans_next;
+ if (prev) {
+ if (next) {
+ prev->trans_next = next;
+ next->trans_prev = prev;
+ }
+ else {
+ prev->trans_next = NULL;
+ tr->req_info.tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->trans_prev = NULL;
+ tr->req_info.head = next;
+ }
+ else {
+ tr->req_info.head = NULL;
+ tr->req_info.tail = NULL;
+ }
+ }
+
+ cur_req->trans_prev = NULL;
+ cur_req->trans_next = NULL;
+
+ tr->req_info.num_req --;
+
+ H5VL_iod_request_decr_rc(cur_req);
+
+ cur_req = next_req;
+ }
+ HDassert(0 == tr->req_info.num_req);
+ }
+
+ status = (int *)malloc(sizeof(int));
+
+#if H5VL_IOD_DEBUG
+ printf("Transaction Abort, tr %"PRIu64", axe id %"PRIu64"\n",
+ input.trans_num, g_axe_id);
+#endif
+
+ if(H5VL__iod_create_and_forward(H5VL_TR_ABORT_ID, HG_TR_ABORT,
+ (H5VL_iod_object_t *)tr->file, 0,
+ num_parents, parent_reqs,
+ NULL, &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_tr_abort() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_prefetch
+ *
+ * Purpose: prefetched an object from BB to Central storage and returns
+ * a replica ID for access to the prefetched object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_prefetch(void *_obj, hid_t rcxt_id, hrpl_t *replica_id, hid_t apl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ prefetch_in_t input;
+ H5RC_t *rc = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(obj->file, obj) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(obj->request && H5VL_IOD_PENDING == obj->request->state) {
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait for request")
+ }
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ input.coh = obj->file->remote_file.coh;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.apl_id = apl_id;
+ input.obj_type = obj->obj_type;
+
+ switch(obj->obj_type) {
+ case H5I_DATASET:
+ {
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)obj;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ break;
+ }
+ case H5I_DATATYPE:
+ {
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)obj;
+ input.iod_id = dtype->remote_dtype.iod_id;
+ input.iod_oh = dtype->remote_dtype.iod_oh;
+ break;
+ }
+ case H5I_GROUP:
+ {
+ H5VL_iod_group_t *group = (H5VL_iod_group_t *)obj;
+ input.iod_id = group->remote_group.iod_id;
+ input.iod_oh = group->remote_group.iod_oh;
+ break;
+ }
+ case H5I_MAP:
+ {
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)obj;
+ input.iod_id = map->remote_map.iod_id;
+ input.iod_oh = map->remote_map.iod_oh;
+ break;
+ }
+ case H5I_ATTR:
+ {
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+ input.iod_id = attr->remote_attr.iod_id;
+ input.iod_oh = attr->remote_attr.iod_oh;
+ break;
+ }
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_VIEW:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "not a valid object to prefetch");
+ }
+
+ if(H5VL__iod_create_and_forward(H5VL_PREFETCH_ID, HG_PREFETCH,
+ obj, 1, 0, NULL, NULL,
+ &input, replica_id, replica_id, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_prefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_evict
+ *
+ * Purpose: evicts an object from BB.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_evict(void *_obj, uint64_t c_version, hid_t apl_id, void **req)
+{
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj;
+ evict_in_t input;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ int *status = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If this call is not asynchronous, complete and remove all
+ requests that are associated with this object from the List */
+ if(NULL == req) {
+ if(H5VL_iod_request_wait_some(obj->file, obj) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on all object requests");
+ }
+
+ if(obj->request && H5VL_IOD_PENDING == obj->request->state) {
+ if(H5VL_iod_request_wait(obj->file, obj->request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait for request")
+ }
+
+ if(NULL == (plist = H5P_object_verify(apl_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not an access plist");
+ if(H5P_get(plist, H5O_ACS_REPLICA_ID_NAME, &input.replica_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value");
+
+ input.coh = obj->file->remote_file.coh;
+ input.rcxt_num = c_version;
+ input.cs_scope = obj->file->md_integrity_scope;
+ input.apl_id = apl_id;
+
+ switch(obj->obj_type) {
+ case H5I_DATASET:
+ {
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)obj;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ break;
+ }
+ case H5I_DATATYPE:
+ {
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)obj;
+ input.iod_id = dtype->remote_dtype.iod_id;
+ input.iod_oh = dtype->remote_dtype.iod_oh;
+ break;
+ }
+ case H5I_GROUP:
+ {
+ H5VL_iod_group_t *group = (H5VL_iod_group_t *)obj;
+ input.iod_id = group->remote_group.iod_id;
+ input.iod_oh = group->remote_group.iod_oh;
+ break;
+ }
+ case H5I_MAP:
+ {
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)obj;
+ input.iod_id = map->remote_map.iod_id;
+ input.iod_oh = map->remote_map.iod_oh;
+ break;
+ }
+ case H5I_ATTR:
+ {
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)obj;
+ input.iod_id = attr->remote_attr.iod_id;
+ input.iod_oh = attr->remote_attr.iod_oh;
+ break;
+ }
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_FILE:
+ case H5I_DATASPACE:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_VIEW:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "not a valid object to evict");
+ }
+
+ status = (int *)malloc(sizeof(int));
+
+ if(H5VL__iod_create_and_forward(H5VL_EVICT_ID, HG_EVICT,
+ obj, 1, 0, NULL, NULL,
+ &input, status, status, req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship VOL op");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_evict() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_cancel
+ *
+ * Purpose: Cancel an asynchronous operation
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Mohamad Chaarawi
+ * April 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_cancel(void **req, H5ES_status_t *status)
+{
+ H5VL_iod_request_t *request = *((H5VL_iod_request_t **)req);
+ hg_status_t hg_status;
+ int ret;
+ H5VL_iod_state_t state;
+ hg_request_t hg_req; /* Local function shipper request, for sync. operations */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* request has completed already, can not cancel */
+ if(request->state == H5VL_IOD_COMPLETED) {
+ /* Call the completion function to check return values and free resources */
+ if(H5VL_iod_request_complete(request->obj->file, request) < 0)
+ fprintf(stderr, "Operation Failed!\n");
+
+ *status = request->status;
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+
+ /* forward the cancel call to the IONs */
+ if(HG_Forward(PEER, H5VL_CANCEL_OP_ID, &request->axe_id, &state, &hg_req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship attribute write");
+
+ /* Wait on the cancel request to return */
+ ret = HG_Wait(hg_req, HG_MAX_IDLE_TIME, &hg_status);
+
+ /* If the actual wait Fails, then the status of the cancel
+ operation is unknown */
+ if(HG_FAIL == ret)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to wait on cancel request")
+ else {
+ if(hg_status) {
+ /* If the operation to be canceled has already completed,
+ mark it so and complete it locally */
+ if(state == H5VL_IOD_COMPLETED) {
+ if(H5VL_IOD_PENDING == request->state) {
+ if(H5VL_iod_request_wait(request->obj->file, request) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait for request");
+ }
+
+ *status = request->status;
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+
+ /* if the status returned is cancelled, then cancel it
+ locally too */
+ else if (state == H5VL_IOD_CANCELLED) {
+ request->status = H5ES_STATUS_CANCEL;
+ request->state = H5VL_IOD_CANCELLED;
+ if(H5VL_iod_request_cancel(request->obj->file, request) < 0)
+ fprintf(stderr, "Operation Failed!\n");
+
+ *status = request->status;
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+ }
+ else
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Cancel Operation taking too long. Aborting");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_cancel() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_test
+ *
+ * Purpose: Test for an asynchronous operation's completion
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_test(void **req, H5ES_status_t *status)
+{
+ H5VL_iod_request_t *request = *((H5VL_iod_request_t **)req);
+ hg_status_t hg_status;
+ int ret;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Test completion of the request if is still pending */
+ if(H5VL_IOD_PENDING == request->state) {
+ ret = HG_Wait(*((hg_request_t *)request->req), 0, &hg_status);
+ if(HG_FAIL == ret) {
+ fprintf(stderr, "failed to wait on request\n");
+ request->status = H5ES_STATUS_FAIL;
+ request->state = H5VL_IOD_COMPLETED;
+
+ /* remove the request from the file linked list */
+ H5VL_iod_request_delete(request->obj->file, request);
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+ else {
+ if(hg_status) {
+ request->status = H5ES_STATUS_SUCCEED;
+ request->state = H5VL_IOD_COMPLETED;
+
+ /* Call the completion function to check return values and free resources */
+ if(H5VL_iod_request_complete(request->obj->file, request) < 0)
+ fprintf(stderr, "Operation Failed!\n");
+
+ *status = request->status;
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+ /* request has not finished, set return status appropriately */
+ else
+ *status = request->status;
+ }
+ }
+ else {
+ *status = request->status;
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+ }
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_test() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_wait
+ *
+ * Purpose: Wait for an asynchronous operation to complete
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 20, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_iod_wait(void **req, H5ES_status_t *status)
+{
+ H5VL_iod_request_t *request = *((H5VL_iod_request_t **)req);
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Wait on completion of the request if it was not completed */
+ if(H5VL_IOD_PENDING == request->state) {
+ if(H5VL_iod_request_wait(request->obj->file, request) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait for request")
+ }
+
+ *status = request->status;
+
+ /* free the mercury request */
+ request->req = H5MM_xfree(request->req);
+
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_wait() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod.h b/src/H5VLiod.h
new file mode 100644
index 0000000..c29d234
--- /dev/null
+++ b/src/H5VLiod.h
@@ -0,0 +1,83 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * January, 2012
+ *
+ * Purpose: The public header file for the IOD VOL plugin.
+ */
+#ifndef H5VLiod_H
+#define H5VLiod_H
+
+#ifdef H5_HAVE_EFF
+
+#include "axe.h"
+#include "iod_api.h"
+#include "iod_types.h"
+#include "mercury.h"
+#include "mercury_handler.h"
+#include "mercury_macros.h"
+#include "mercury_proc_string.h"
+#include "na_mpi.h"
+
+#define H5VL_IOD (H5VL_iod_init())
+#else
+#define H5VL_IOD (-1)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef H5_HAVE_EFF
+
+#define H5D_XFER_INJECT_CORRUPTION_NAME "inject_corruption"
+#define H5D_XFER_CHECKSUM_NAME "checksum"
+#define H5D_XFER_CHECKSUM_PTR_NAME "checksum_ptr"
+#define H5D_CRT_APPEND_ONLY_NAME "append_only"
+#define H5O_CRT_ENABLE_CHECKSUM_NAME "enable_obj_checksum"
+#define H5O_ACS_REPLICA_ID_NAME "replica_id"
+
+H5_DLL H5VL_class_t *H5VL_iod_init(void);
+H5_DLL herr_t H5Pset_fapl_iod(hid_t fapl_id, MPI_Comm comm, MPI_Info info);
+H5_DLL herr_t EFF_start_server(MPI_Comm comm, MPI_Info info);
+H5_DLL herr_t EFF_init(MPI_Comm comm, MPI_Info info);
+H5_DLL herr_t EFF_finalize(void);
+
+H5_DLL herr_t H5Pset_lapl_replica_id(hid_t lapl_id, hrpl_t replica_id);
+H5_DLL herr_t H5Pget_lapl_replica_id(hid_t lapl_id, hrpl_t *replica_id);
+H5_DLL herr_t H5Pset_ocpl_enable_checksum(hid_t ocpl_id, hbool_t flag);
+H5_DLL herr_t H5Pget_ocpl_enable_checksum(hid_t ocpl_id, hbool_t *flag);
+H5_DLL herr_t H5Pset_dxpl_checksum(hid_t dxpl_id, uint64_t value);
+H5_DLL herr_t H5Pget_dxpl_checksum(hid_t dxpl_id, uint64_t *value);
+H5_DLL herr_t H5Pset_dxpl_checksum_ptr(hid_t dxpl_id, uint64_t *value);
+H5_DLL herr_t H5Pget_dxpl_checksum_ptr(hid_t dxpl_id, uint64_t **value);
+H5_DLL herr_t H5Pset_metadata_integrity_scope(hid_t fapl_id, uint32_t scope);
+H5_DLL herr_t H5Pget_metadata_integrity_scope(hid_t fapl_id, uint32_t *scope);
+H5_DLL herr_t H5Pset_rawdata_integrity_scope(hid_t dxpl_id, uint32_t scope);
+H5_DLL herr_t H5Pget_rawdata_integrity_scope(hid_t dxpl_id, uint32_t *scope);
+H5_DLL herr_t H5Pset_dxpl_inject_corruption(hid_t dxpl_id, hbool_t flag);
+H5_DLL herr_t H5Pget_dxpl_inject_corruption(hid_t dxpl_id, hbool_t *flag);
+H5_DLL herr_t H5Pset_dcpl_append_only(hid_t dcpl_id, hbool_t flag);
+H5_DLL herr_t H5Pget_dcpl_append_only(hid_t dcpl_id, hbool_t *flag);
+
+#endif /* H5_HAVE_EFF */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _H5VLiod_H */
diff --git a/src/H5VLiod_analysis.c b/src/H5VLiod_analysis.c
new file mode 100644
index 0000000..a40f64d
--- /dev/null
+++ b/src/H5VLiod_analysis.c
@@ -0,0 +1,1307 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: Routines to support Analysis Shipping.
+ */
+
+#include "H5VLiod_server.h"
+
+#include "H5Qpublic.h"
+
+#ifdef H5_HAVE_PYTHON
+#include <Python.h>
+#include <numpy/ndarrayobject.h>
+#endif
+
+#ifdef H5_HAVE_EFF
+
+/* User data for dataspace iteration to query elements. */
+typedef struct {
+ size_t num_elmts;
+ hid_t query_id;
+ hid_t space_query;
+} H5VL__iod_get_query_data_t;
+
+/* do not change order */
+typedef struct {
+ analysis_farm_out_t farm_out;
+ void *data;
+} H5VLiod_farm_data_t;
+
+#ifdef H5_HAVE_PYTHON
+
+static hbool_t numpy_initialized = FALSE;
+static void H5VL__iod_numpy_init(void);
+
+static PyObject *H5VL__iod_load_script(const char *script, const char *func_name);
+
+static herr_t H5VL__iod_translate_h5_type(hid_t data_type_id,
+ enum NPY_TYPES *npy_type);
+
+static herr_t H5VL__iod_translate_numpy_type(enum NPY_TYPES npy_type,
+ hid_t *data_type_id, size_t *data_type_size);
+
+static PyObject *H5VL__iod_create_numpy_array(size_t num_elmts, hid_t data_type_id,
+ void *data);
+
+static herr_t H5VL__iod_extract_numpy_array(PyObject *numpy_array, void **data,
+ size_t *num_elmts, hid_t *data_type_id);
+
+/* TODO define as static but leave it like this for testing */
+herr_t H5VL__iod_split(const char *split_script, void *data,
+ size_t num_elmts, hid_t data_type_id, void **split_data,
+ size_t *split_num_elmts, hid_t *split_data_type_id);
+
+herr_t H5VL__iod_combine(const char *combine_script,
+ void **split_data, size_t *split_num_elmts,
+ size_t num_targets, hid_t data_type_id,
+ void **combine_data, size_t *combine_num_elmts,
+ hid_t *combine_data_type_id);
+
+#endif
+
+static herr_t H5VL__iod_farm_split(iod_handle_t coh, iod_obj_id_t obj_id, iod_trans_id_t rtid,
+ hid_t space_id, coords_t coords, iod_size_t num_cells,
+ hid_t type_id, hid_t query_id,
+ const char *split_script, void **split_data,
+ size_t *split_num_elmts, hid_t *split_type_id);
+
+static hid_t H5VL__iod_get_space_layout(coords_t coords, iod_size_t num_cells, hid_t space_id);
+
+static herr_t H5VL__iod_get_query_data_cb(void *elem, hid_t type_id, unsigned ndim,
+ const hsize_t *point, void *_udata);
+
+static herr_t H5VL__iod_get_query_data(iod_handle_t coh, iod_obj_id_t dset_id,
+ iod_trans_id_t rtid, hid_t query_id,
+ hid_t space_id, hid_t type_id,
+ size_t *num_elmts, void **data);
+
+static herr_t H5VL__iod_read_selection(iod_handle_t coh, iod_obj_id_t obj_id,
+ iod_trans_id_t rtid, hid_t space_id,
+ hid_t type_id, void *buf);
+
+#ifdef H5_HAVE_PYTHON
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_numpy_init
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+H5VL__iod_numpy_init(void)
+{
+ /* Needed for numpy stuff */
+ /* Note: This function must be called in the initialization section of a
+ * module that will make use of the C-API. It imports the module where the
+ * function-pointer table is stored and points the correct variable to it.
+ * If, however, the extension module involves multiple files where the C-API
+ * is needed then some additional steps must be taken. */
+ import_array();
+ numpy_initialized = TRUE;
+} /* end H5VL__iod_numpy_init() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_load_script
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static PyObject *
+H5VL__iod_load_script(const char *script, const char *func_name)
+{
+ PyObject *po_func = NULL, *ret_value = NULL; /* Return value */
+ PyObject *po_main = NULL, *po_main_dict = NULL, *po_rstring = NULL;
+ /* for reference in case we need it
+ PyObject *main = PyImport_AddModule("__main__");
+ PyObject *dlfl = PyImport_AddModule("dlfl");
+ PyObject* main_dict = PyModule_GetDict( main );
+ PyObject* dlfl_dict = PyModule_GetDict( dlfl );
+ */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get reference to main */
+ if(NULL == (po_main = PyImport_AddModule("__main__")))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, NULL, "can't get reference to main module");
+
+ if(NULL == (po_main_dict = PyModule_GetDict(po_main)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, NULL, "can't get dictionary from main module");
+
+ /* Load script */
+ if(NULL == (po_rstring = PyRun_String(script, Py_file_input, po_main_dict, po_main_dict)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, NULL, "can't load script into main module");
+
+ /* Get reference to function name */
+ if(NULL == (po_func = PyObject_GetAttrString(po_main, func_name)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, NULL, "can't get reference to function");
+
+ ret_value = po_func;
+
+done:
+ Py_DECREF(po_rstring);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_load_script() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_translate_h5_type
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_translate_h5_type(hid_t data_type_id, enum NPY_TYPES *npy_type)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ enum NPY_TYPES translated_type;
+ hid_t native_datatype_id;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if((native_datatype_id = H5Tget_native_type(data_type_id, H5T_DIR_DEFAULT)) < 0)
+ HGOTO_ERROR2(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type");
+
+ if(H5Tequal(native_datatype_id, H5T_NATIVE_LLONG_g))
+ translated_type = NPY_LONGLONG;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_LONG_g))
+ translated_type = NPY_LONG;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_INT_g))
+ translated_type = NPY_INT;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_SHORT_g))
+ translated_type = NPY_SHORT;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_SCHAR_g))
+ translated_type = NPY_BYTE;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_DOUBLE_g))
+ translated_type = NPY_DOUBLE;
+ else if(H5Tequal(native_datatype_id, H5T_NATIVE_FLOAT_g))
+ translated_type = NPY_FLOAT;
+ else
+ HGOTO_ERROR2(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid type")
+
+ if(FAIL == H5Tclose(native_datatype_id))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype");
+
+ *npy_type = translated_type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_translate_h5_type() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_translate_numpy_type
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_translate_numpy_type(enum NPY_TYPES npy_type, hid_t *data_type_id,
+ size_t *data_type_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ hid_t translated_type_id;
+ size_t translated_type_size;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch (npy_type) {
+ case NPY_LONGLONG:
+ translated_type_id = H5T_NATIVE_LLONG_g;
+ break;
+ case NPY_LONG:
+ translated_type_id = H5T_NATIVE_LONG_g;
+ break;
+ case NPY_INT:
+ translated_type_id = H5T_NATIVE_INT_g;
+ break;
+ case NPY_SHORT:
+ translated_type_id = H5T_NATIVE_SHORT_g;
+ break;
+ case NPY_BYTE:
+ translated_type_id = H5T_NATIVE_SCHAR_g;
+ break;
+ case NPY_DOUBLE:
+ translated_type_id = H5T_NATIVE_DOUBLE_g;
+ break;
+ case NPY_FLOAT:
+ translated_type_id = H5T_NATIVE_FLOAT_g;
+ break;
+ default:
+ HGOTO_ERROR2(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid type")
+ break;
+ }
+
+ if (0 == (translated_type_size = H5Tget_size(translated_type_id)))
+ HGOTO_ERROR2(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size")
+
+ *data_type_id = translated_type_id;
+ *data_type_size = translated_type_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_translate_numpy_type() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_create_numpy_array
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static PyObject *
+H5VL__iod_create_numpy_array(size_t num_elmts, hid_t data_type_id, void *data)
+{
+ PyObject *ret_value = NULL; /* Return value */
+ npy_intp dim[1] = {(npy_intp) num_elmts};
+ enum NPY_TYPES npy_type;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(data);
+
+ /* Convert data_type to numpy type */
+ if(FAIL == H5VL__iod_translate_h5_type(data_type_id, &npy_type))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTCONVERT, NULL, "unable to translate datatype to NPY type");
+
+ ret_value = PyArray_SimpleNewFromData(1, dim, npy_type, data);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_create_numpy_array() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_extract_numpy_array
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_extract_numpy_array(PyObject *numpy_array, void **data,
+ size_t *num_elmts, hid_t *data_type_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ void *numpy_data = NULL, *extracted_data = NULL;
+ hid_t extracted_datatype_id;
+ npy_intp *numpy_dims;
+ int numpy_datatype;
+ size_t numpy_num_elmts, extracted_datatype_size;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(numpy_array);
+ HDassert(data);
+ HDassert(num_elmts);
+ HDassert(data_type_id);
+
+ /* Input array should be 1D */
+ if(PyArray_NDIM(numpy_array) > 1)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "was expecting 1-dimensional array")
+
+ if(NULL == (numpy_data = PyArray_DATA(numpy_array)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get data from numpy array")
+
+ if(NULL == (numpy_dims = PyArray_DIMS(numpy_array)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimensions from numpy array")
+ numpy_num_elmts = (size_t) numpy_dims[0];
+
+ if(0 == (numpy_datatype = PyArray_TYPE(numpy_array)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get type from numpy array")
+
+ /* Translate NPY type to hid_t */
+ if(FAIL == H5VL__iod_translate_numpy_type(numpy_datatype, &extracted_datatype_id,
+ &extracted_datatype_size))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCONVERT, FAIL, "can't translate NPY type")
+
+ /* Copy data from NPY array */
+ if(NULL == (extracted_data = H5MM_malloc(numpy_num_elmts * extracted_datatype_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTALLOC, FAIL, "can't allocate extracted data")
+ HDmemcpy(extracted_data, numpy_data, numpy_num_elmts * extracted_datatype_size);
+
+ *data = extracted_data;
+ *num_elmts = numpy_num_elmts;
+ *data_type_id = extracted_datatype_id;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__iod_extract_numpy_array */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_split
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__iod_split(const char *split_script, void *data, size_t num_elmts,
+ hid_t data_type_id, void **split_data, size_t *split_num_elmts,
+ hid_t *split_data_type_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ PyObject *po_func = NULL, *po_numpy_array = NULL, *po_args_tup = NULL;
+ PyObject *po_numpy_array_split = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(!numpy_initialized) H5VL__iod_numpy_init();
+
+ /* Create numpy array */
+ if(NULL == (po_numpy_array = H5VL__iod_create_numpy_array(num_elmts, data_type_id, data)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create numpy array from data")
+
+ /* Load script */
+ if(NULL == (po_func = H5VL__iod_load_script(split_script, "split")))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't load split script")
+
+ /* Check whether split is defined as function in given script */
+ if(0 == PyCallable_Check(po_func))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't find split function")
+
+ /* Get the input to function */
+ if(NULL == (po_args_tup = PyTuple_Pack(1, po_numpy_array)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't set input to split function")
+
+ /* Invoke the split function */
+ if(NULL == (po_numpy_array_split = PyObject_CallObject(po_func, po_args_tup)))
+ HGOTO_ERROR2(H5E_SYM, H5E_BADVALUE, FAIL, "returned NULL python object")
+
+ /* Extract data from numpy array */
+ if(FAIL == H5VL__iod_extract_numpy_array(po_numpy_array_split, split_data,
+ split_num_elmts, split_data_type_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCREATE, FAIL, "can't extract data from numpy array")
+
+done:
+ /* Cleanup */
+ Py_XDECREF(po_func);
+ Py_XDECREF(po_args_tup);
+ Py_XDECREF(po_numpy_array);
+ Py_XDECREF(po_numpy_array_split);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_split() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_combine
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__iod_combine(const char *combine_script, void **split_data, size_t *split_num_elmts,
+ size_t num_targets, hid_t data_type_id, void **combine_data,
+ size_t *combine_num_elmts, hid_t *combine_data_type_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ PyObject *po_func = NULL, *po_numpy_arrays = NULL, *po_args_tup = NULL;
+ PyObject *po_numpy_array_combine = NULL;
+ size_t i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(!numpy_initialized) H5VL__iod_numpy_init();
+
+ /* Create numpy arrays */
+ if(NULL == (po_numpy_arrays = PyList_New((Py_ssize_t) num_targets)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create list of arrays")
+ for(i = 0; i < num_targets; i++) {
+ PyObject *po_numpy_array = NULL;
+ int py_ret = 0;
+
+ if(NULL == (po_numpy_array =
+ H5VL__iod_create_numpy_array(split_num_elmts[i],
+ data_type_id,
+ split_data[i])))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create numpy array from data")
+
+ if(0 != (py_ret = PyList_SetItem(po_numpy_arrays, (Py_ssize_t) i, po_numpy_array)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't set item to array list")
+ }
+
+ /* Load script */
+ if(NULL == (po_func = H5VL__iod_load_script(combine_script, "combine")))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't load combine script")
+
+ /* Check whether split is defined as function in given script */
+ if(0 == PyCallable_Check(po_func))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't find combine function")
+
+ /* Get the input to function */
+ if(NULL == (po_args_tup = PyTuple_Pack(1, po_numpy_arrays)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTLOAD, FAIL, "can't set input to combine function")
+
+ /* Invoke the split function */
+ if(NULL == (po_numpy_array_combine = PyObject_CallObject(po_func, po_args_tup)))
+ HGOTO_ERROR2(H5E_SYM, H5E_BADVALUE, FAIL, "returned NULL python object")
+
+ /* Extract data from numpy array */
+ if(FAIL == H5VL__iod_extract_numpy_array(po_numpy_array_combine, combine_data,
+ combine_num_elmts, combine_data_type_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCREATE, FAIL, "can't extract data from numpy array")
+
+done:
+ /* Cleanup */
+ Py_XDECREF(po_func);
+ Py_XDECREF(po_args_tup);
+ for(i = 0; i < num_targets; i++) {
+ Py_XDECREF(po_numpy_arrays + i);
+ }
+ Py_XDECREF(po_numpy_array_combine);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+#endif /* H5_HAVE_PYTHON */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_request_container_open
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_request_container_open(const char *file_name, iod_handle_t **cohs)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ hg_request_t *hg_reqs = NULL;
+ iod_handle_t *temp_cohs = NULL;
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (hg_reqs = (hg_request_t *)malloc(sizeof(hg_request_t) * (unsigned int) num_ions_g)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate HG requests");
+
+ if(NULL == (temp_cohs = (iod_handle_t *)malloc(sizeof(iod_handle_t) * (unsigned int) num_ions_g)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate container handles");
+
+ /* forward a call to every ION to open the container */
+ for(i = 1; i < num_ions_g; i++) {
+ if(HG_Forward(server_addr_g[i], H5VL_EFF_OPEN_CONTAINER, &file_name,
+ &temp_cohs[i], &hg_reqs[i]) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+ }
+
+ /* open the container */
+ printf("(%d) Calling iod_container_open on %s\n", my_rank_g, file_name);
+ if(iod_container_open(file_name, NULL, IOD_CONT_R, &temp_cohs[0], NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open file");
+
+ for(i = 1; i < num_ions_g; i++) {
+ if(HG_Wait(hg_reqs[i], HG_MAX_IDLE_TIME, HG_STATUS_IGNORE) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "HG_Wait Failed");
+
+ /* Free Mercury request */
+ if(HG_Request_free(hg_reqs[i]) != HG_SUCCESS)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+ }
+ free(hg_reqs);
+
+ *cohs = temp_cohs;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_request_container_open */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_request_container_close
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_request_container_close(iod_handle_t *cohs)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ hg_request_t *hg_reqs = NULL;
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (hg_reqs = (hg_request_t *)malloc(sizeof(hg_request_t) * (unsigned int) num_ions_g)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate HG requests");
+
+ /* forward a call to every ION to close the container */
+ for(i = 1; i < num_ions_g; i++) {
+ if(HG_Forward(server_addr_g[i], H5VL_EFF_CLOSE_CONTAINER, &cohs[i],
+ &ret_value, &hg_reqs[i]) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+ }
+
+ /* close the container */
+ if(iod_container_close(cohs[0], NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTDEC, FAIL, "can't close container");
+
+ for(i = 1; i < num_ions_g; i++) {
+ if(HG_Wait(hg_reqs[i], HG_MAX_IDLE_TIME, HG_STATUS_IGNORE) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "HG_Wait Failed");
+
+ /* Free Mercury request */
+ if(HG_Request_free(hg_reqs[i]) != HG_SUCCESS)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+ }
+ free(hg_reqs);
+ free(cohs);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_request_container_close */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_farm_work
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_farm_work(iod_obj_map_t *obj_map, iod_handle_t *cohs,
+ iod_obj_id_t obj_id, iod_trans_id_t rtid,
+ hid_t space_id, hid_t type_id, hid_t query_id,
+ const char *split_script, const char *combine_script)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ void **split_data;
+ size_t *split_num_elmts;
+ void *combine_data;
+ size_t combine_num_elmts;
+ hid_t split_type_id = FAIL, combine_type_id = FAIL;
+ hg_request_t *hg_reqs = NULL;
+ unsigned int i;
+ unsigned int num_targets = obj_map->u_map.array_map.n_range;
+ analysis_farm_in_t farm_input;
+ analysis_farm_out_t *farm_output = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* function shipper requests */
+ if(NULL == (hg_reqs = (hg_request_t *) malloc(sizeof(hg_request_t) * num_targets)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate HG requests");
+
+ if(NULL == (farm_output = (analysis_farm_out_t *) malloc(sizeof(analysis_farm_out_t) * num_targets)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate HG requests");
+
+ if(NULL == (split_data = (void **) malloc(sizeof(void *) * num_targets)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for split data");
+
+ if(NULL == (split_num_elmts = (size_t *) malloc(sizeof(size_t) * num_targets)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for num elmts");
+
+ farm_input.obj_id = obj_id;
+ farm_input.rtid = rtid;
+ farm_input.space_id = space_id;
+ farm_input.type_id = type_id;
+ farm_input.query_id = query_id;
+ farm_input.split_script = split_script;
+
+ for (i = 0; i < obj_map->u_map.array_map.n_range; i++) {
+ unsigned int j;
+ unsigned int server_idx = 0;
+ farm_input.num_cells = obj_map->u_map.array_map.array_range[i].n_cell;
+ farm_input.coords.rank = H5Sget_simple_extent_ndims(space_id);
+ farm_input.coords.start_cell = obj_map->u_map.array_map.array_range[i].start_cell;
+ farm_input.coords.end_cell = obj_map->u_map.array_map.array_range[i].end_cell;
+
+ for (j = 0; j < (unsigned int) num_ions_g; j++) {
+ if (0 == strcmp(obj_map->u_map.array_map.array_range[i].loc,
+ server_loc_g[j])) {
+ server_idx = j;
+ printf("(%d) Server %d owns this object\n", my_rank_g, server_idx);
+ break;
+ }
+ }
+
+ farm_input.server_idx = server_idx;
+ farm_input.coh = cohs[server_idx];
+
+ /* forward the call to the target server */
+ if (server_idx == 0) {
+ hg_reqs[i] = HG_REQUEST_NULL;
+ /* Do a local split */
+ if(FAIL == H5VL__iod_farm_split(cohs[0], obj_id, rtid, space_id,
+ farm_input.coords, farm_input.num_cells, type_id, query_id, split_script,
+ &split_data[i], &split_num_elmts[i], &split_type_id))
+ HGOTO_ERROR2(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't split in farmed job");
+ } else {
+ if(HG_Forward(server_addr_g[server_idx],
+ H5VL_EFF_ANALYSIS_FARM, &farm_input, &farm_output[i],
+ &hg_reqs[i]) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+ }
+ }
+
+ for (i = 0; i < num_targets; i++) {
+ if (hg_reqs[i] == HG_REQUEST_NULL) {
+ /* No request / was local */
+ } else {
+ analysis_transfer_in_t transfer_input;
+ analysis_transfer_out_t transfer_output;
+ hg_bulk_t bulk_handle;
+ size_t split_data_size;
+ unsigned int server_idx;
+
+ /* Wait for the farmed work to complete */
+ if(HG_Wait(hg_reqs[i], HG_MAX_IDLE_TIME, HG_STATUS_IGNORE) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "HG_Wait Failed");
+
+ /* Get split type ID and num_elemts (all the arrays should have the same native type id) */
+ server_idx = farm_output[i].server_idx;
+ split_type_id = farm_output[i].type_id;
+ split_num_elmts[i] = farm_output[i].num_elmts;
+ split_data_size = split_num_elmts[i] * H5Tget_size(split_type_id);
+// printf("Getting %d elements of size %zu from server %zu\n",
+// split_num_elmts[i], H5Tget_size(split_type_id), server_idx);
+
+ if(NULL == (split_data[i] = malloc(split_data_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate farm buffer");
+
+ HG_Bulk_handle_create(split_data[i], split_data_size,
+ HG_BULK_READWRITE, &bulk_handle);
+
+ transfer_input.axe_id = farm_output[i].axe_id;
+ transfer_input.bulk_handle = bulk_handle;
+
+ /* forward a free call to the target server */
+ if(HG_Forward(server_addr_g[server_idx], H5VL_EFF_ANALYSIS_FARM_TRANSFER,
+ &transfer_input, &transfer_output, &hg_reqs[i]) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+
+ /* Wait for the farmed work to complete */
+ if(HG_Wait(hg_reqs[i], HG_MAX_IDLE_TIME, HG_STATUS_IGNORE) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "HG_Wait Failed");
+
+ /* Free bulk handle */
+ HG_Bulk_handle_free(bulk_handle);
+
+ /* Free Mercury request */
+ if(HG_Request_free(hg_reqs[i]) != HG_SUCCESS)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+ }
+ }
+
+ if(hg_reqs)
+ free(hg_reqs);
+ if(farm_output)
+ free(farm_output);
+
+ printf("(%d) Applying combine on data\n", my_rank_g);
+#ifdef H5_HAVE_PYTHON
+ if (H5VL__iod_combine(combine_script, split_data, split_num_elmts,
+ num_targets, split_type_id, &combine_data,
+ &combine_num_elmts, &combine_type_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't combine split data");
+#endif
+
+ /* free farm data */
+ if (split_data) {
+ for (i = 0; i < num_targets; i++) {
+ free(split_data[i]);
+ }
+ free(split_data);
+ }
+ free(split_num_elmts);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_farm_work */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_execute_cb
+ *
+ * Purpose: Retrieves layout of object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_analysis_execute_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ analysis_execute_in_t *input = (analysis_execute_in_t *)op_data->input;
+ analysis_execute_out_t output;
+ const char *file_name = input->file_name;
+ const char *obj_name = input->obj_name;
+ hid_t query_id = input->query_id;
+ const char *split_script = input->split_script;
+ const char *combine_script = input->combine_script;
+ hid_t space_id = FAIL, type_id = FAIL;
+ iod_cont_trans_stat_t *tids = NULL;
+ iod_trans_id_t rtid;
+ iod_handle_t *cohs; /* the container handle */
+ iod_handles_t root_handle; /* root handle */
+ iod_obj_id_t obj_id; /* The ID of the object */
+ iod_handles_t obj_oh; /* object handle */
+ iod_handle_t mdkv_oh;
+ scratch_pad sp;
+ iod_obj_map_t *obj_map = NULL;
+ unsigned int i;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* ****************** TEMP THING (as IOD requires collective container open) */
+
+ if(FAIL == H5VL__iod_request_container_open(file_name, &cohs))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't request container open");
+
+ /* ***************** END TEMP THING */
+
+ if(iod_query_cont_trans_stat(cohs[0], &tids, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get container tids status");
+
+ rtid = tids->latest_rdable;
+
+ if(iod_free_cont_trans_stat(cohs[0], tids) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free container transaction status object");
+
+ if(iod_trans_start(cohs[0], &rtid, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't start transaction");
+
+ root_handle.rd_oh.cookie = IOD_OH_UNDEFINED;
+ root_handle.wr_oh.cookie = IOD_OH_UNDEFINED;
+
+ /* Traverse Path to retrieve object ID, and open object */
+ if(H5VL_iod_server_open_path(cohs[0], ROOT_ID, root_handle, obj_name,
+ rtid, 7, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ printf("(%d) coh %"PRIu64" objoh %"PRIu64" objid %"PRIx64" rtid %"PRIu64"\n",
+ my_rank_g, cohs[0].cookie, obj_oh.rd_oh.cookie, obj_id, rtid);
+
+ printf("Calling iod_obj_query_map\n");
+ ret = iod_obj_query_map(obj_oh.rd_oh, rtid, &obj_map, NULL);
+ if (ret != 0) {
+ printf("iod_obj_query_map failed, ret: %d (%s).\n", ret, strerror(-ret));
+ assert(0);
+ }
+
+ printf("(%d) %-10d\n", my_rank_g, obj_map->u_map.array_map.n_range);
+ for (i = 0; i < obj_map->u_map.array_map.n_range; i++) {
+ printf("(%d) range: %d, start: %zu %zu, "
+ "end: %zu %zu, n_cell: %zu, "
+ "loc: %s\n", my_rank_g, i,
+ obj_map->u_map.array_map.array_range[i].start_cell[0],
+ obj_map->u_map.array_map.array_range[i].start_cell[1],
+ obj_map->u_map.array_map.array_range[i].end_cell[0],
+ obj_map->u_map.array_map.array_range[i].end_cell[1],
+ obj_map->u_map.array_map.array_range[i].n_cell,
+ obj_map->u_map.array_map.array_range[i].loc);
+ }
+
+ /* get scratch pad */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, (char *) &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ /* retrieve datatype and dataspace */
+ /* MSC - This applies only to DATASETS for Q6 */
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(cohs[0], sp[0], rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_OBJ_DATATYPE,
+ NULL, NULL, &type_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE,
+ H5VL_IOD_KEY_OBJ_DATASPACE,
+ NULL, NULL, &space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ /*******************************************/
+ /* Farm work */
+ if(FAIL == H5VL__iod_farm_work(obj_map, cohs, obj_id, rtid, space_id, type_id,
+ query_id, split_script, combine_script))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't farm work");
+
+ /********************************************/
+
+ iod_obj_free_map(obj_oh.rd_oh, obj_map);
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ /* close object */
+ if(iod_obj_close(obj_oh.rd_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+
+ if(iod_trans_finish(cohs[0], rtid, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't finish transaction 0");
+
+ /* ****************** TEMP THING (as IOD requires collective container open) */
+
+ printf("Closing container\n");
+ if(FAIL == H5VL__iod_request_container_close(cohs))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't request container close");
+
+ /* ***************** END TEMP THING */
+
+ printf("Analysis DONE\n");
+ /* set output, and return to AS client */
+ output.ret = ret_value;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0)
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ if(space_id)
+ H5Sclose(space_id);
+ if(type_id)
+ H5Tclose(type_id);
+
+ input = (analysis_execute_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_analysis_execute_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_farm_split
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_farm_split(iod_handle_t coh, iod_obj_id_t obj_id, iod_trans_id_t rtid,
+ hid_t space_id, coords_t coords, iod_size_t num_cells,
+ hid_t type_id, hid_t query_id,
+ const char *split_script, void **split_data,
+ size_t *split_num_elmts, hid_t *split_type_id)
+{
+ void *data = NULL;
+ size_t num_elmts;
+ herr_t ret_value = SUCCEED;
+ hid_t space_layout;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(FAIL == (space_layout = H5VL__iod_get_space_layout(coords, num_cells, space_id)))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't generate local dataspace selection");
+
+ if(H5VL__iod_get_query_data(coh, obj_id, rtid, query_id, space_layout,
+ type_id, &num_elmts, &data) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read local data");
+
+ printf("(%d) Applying split on data\n", my_rank_g);
+ /* Apply split python script on data from query */
+#ifdef H5_HAVE_PYTHON
+ if(FAIL == H5VL__iod_split(split_script, data, num_elmts, type_id,
+ split_data, split_num_elmts, split_type_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANAPPLY, FAIL, "can't apply split script to data");
+#endif
+
+ /* Free the data after split operation */
+ H5MM_free(data);
+ data = NULL;
+
+done:
+ if(space_layout)
+ H5Sclose(space_layout);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_farm_work */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_farm_cb
+ *
+ * Purpose: Retrieves layout of object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_analysis_farm_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ analysis_farm_in_t *input = (analysis_farm_in_t *)op_data->input;
+ H5VLiod_farm_data_t *output = NULL;
+ iod_handle_t coh = input->coh;
+ hid_t query_id = input->query_id;
+ hid_t space_id = input->space_id;
+ hid_t type_id = input->type_id;
+ iod_trans_id_t rtid = input->rtid;
+ iod_obj_id_t obj_id = input->obj_id; /* The ID of the object */
+ coords_t coords = input->coords;
+ const char *split_script = input->split_script;
+ iod_size_t num_cells = input->num_cells;
+ void *split_data = NULL;
+ size_t split_num_elmts;
+ hid_t split_type_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(FAIL == H5VL__iod_farm_split(coh, obj_id, rtid, space_id, coords, num_cells,
+ type_id, query_id, split_script,
+ &split_data, &split_num_elmts, &split_type_id))
+ HGOTO_ERROR2(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't split in farmed job");
+
+ /* allocate output struct */
+ if(NULL == (output = (H5VLiod_farm_data_t *)H5MM_malloc(sizeof(H5VLiod_farm_data_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, FAIL, "No Space");
+
+ /* set output, and return to master */
+ output->farm_out.ret = ret_value;
+ output->farm_out.axe_id = op_data->axe_id;
+ output->farm_out.server_idx = input->server_idx;
+ output->farm_out.num_elmts = split_num_elmts;
+ output->farm_out.type_id = split_type_id;
+ output->data = split_data;
+ op_data->output = output;
+
+ HG_Handler_start_output(op_data->hg_handle, &output->farm_out);
+
+done:
+ input = (analysis_farm_in_t *)H5MM_xfree(input);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_analysis_farm_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_farm_transfer_cb
+ *
+ * Purpose: Frees the output from the split operation
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_analysis_transfer_cb(AXE_engine_t axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ analysis_transfer_in_t *input = (analysis_transfer_in_t *)op_data->input;
+ op_data_t *farm_op_data = NULL;
+ void *farm_op_data_ptr = NULL;
+ H5VLiod_farm_data_t *farm_output = NULL;
+ herr_t ret_value = SUCCEED;
+ hg_bulk_t bulk_block_handle;
+ size_t data_size;
+ hg_bulk_request_t bulk_request;
+ na_addr_t source = HG_Handler_get_addr(op_data->hg_handle);
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(AXE_SUCCEED != AXEget_op_data(axe_engine, input->axe_id, &farm_op_data_ptr))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to get farm op_data");
+
+ farm_op_data = (op_data_t *)farm_op_data_ptr;
+ farm_output = (H5VLiod_farm_data_t *)farm_op_data->output;
+
+ data_size = HG_Bulk_handle_get_size(input->bulk_handle);
+ printf("(%d) Transferring split data back to master\n", my_rank_g);
+
+ HG_Bulk_handle_create(farm_output->data, data_size, HG_BULK_READ_ONLY,
+ &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(source,
+ input->bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* free the bds block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle");
+
+ free(farm_output->data);
+ farm_op_data = (op_data_t *)H5MM_xfree(farm_op_data);
+
+done:
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (analysis_transfer_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_analysis_farm_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_get_space_layout
+ *
+ * Purpose: Generates a dataspace from the IOD layout for a particular
+ * ION or OST. The dataspace returned must be closed with H5Sclose().
+ *
+ * Return: Success: space id
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5VL__iod_get_space_layout(coords_t coords, iod_size_t num_cells, hid_t space_id)
+{
+ int ndims, i;
+ hsize_t start[H5S_MAX_RANK];
+ hsize_t block[H5S_MAX_RANK];
+ hsize_t count[H5S_MAX_RANK];
+
+ hid_t space_layout = FAIL, ret_value = FAIL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* retrieve number of dimensions and dimensions. */
+ ndims = H5Sget_simple_extent_ndims(space_id);
+
+ /* copy the original dataspace and reset selection to NONE */
+ if(FAIL == (space_layout = H5Scopy(space_id)))
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace");
+
+ for(i=0 ; i<ndims ; i++) {
+ start[i] = coords.start_cell[i];
+ block[i] = (coords.end_cell[i] - coords.start_cell[i]) + 1;
+ count[i] = 1;
+ }
+
+ if(H5Sselect_hyperslab(space_layout, H5S_SELECT_SET, start, NULL, count, block))
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to add point to selection");
+
+ ret_value = space_layout;
+
+done:
+ if(ret_value < 0) {
+ if(FAIL != space_layout && H5Sclose(space_layout) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_get_space_layout() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_get_query_data_cb
+ *
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_get_query_data_cb(void *elem, hid_t type_id, unsigned ndim,
+ const hsize_t *point, void *_udata)
+{
+ H5VL__iod_get_query_data_t *udata = (H5VL__iod_get_query_data_t *)_udata;
+ hbool_t result;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(ndim == 1);
+
+ /* Apply the query */
+ if(H5Qapply(udata->query_id, &result, type_id, elem) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "unable to apply query to data element");
+
+ /* If element satisfies query, add it to the selection */
+ if (result) {
+ /* TODO remove that after demo */
+ printf("(%d) Element |%d| matches query\n", my_rank_g, *((int *) elem));
+ udata->num_elmts ++;
+ if(H5Sselect_elements(udata->space_query, H5S_SELECT_APPEND, 1, point))
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to add point to selection")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_get_query_data_cb */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_get_query_data
+ *
+ * Purpose: Generates a dataspace from the query specified. The dataspace
+ * returned must be closed with H5Sclose().
+ *
+ * Return: Success: space id
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_get_query_data(iod_handle_t coh, iod_obj_id_t dset_id,
+ iod_trans_id_t rtid, hid_t query_id,
+ hid_t space_id, hid_t type_id,
+ size_t *num_elmts, void **data)
+{
+ hsize_t dims[1];
+ size_t nelmts;
+ size_t elmt_size=0, buf_size=0;
+ H5VL__iod_get_query_data_t udata;
+ void *buf = NULL;
+ hid_t space_query = FAIL, mem_space = FAIL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ nelmts = (size_t) H5Sget_select_npoints(space_id);
+ elmt_size = H5Tget_size(type_id);
+ buf_size = nelmts * elmt_size;
+
+ /* allocate buffer to hold data */
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* read the data local on the ION specified in the layout selection */
+ if(H5VL__iod_read_selection(coh, dset_id, rtid, space_id, type_id, buf) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read local data");
+
+ dims[0] = (hsize_t)nelmts;
+ /* create a 1-D selection to describe the data read in memory */
+ if(FAIL == (mem_space = H5Screate_simple(1, dims, NULL)))
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
+
+ if(FAIL == (space_query = H5Scopy(mem_space)))
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace");
+
+ udata.query_id = query_id;
+ udata.space_query = space_query;
+ udata.num_elmts = 0;
+
+ /* iterate over every element and apply the query on it. If the
+ query is not satisfied, then remove it from the query selection */
+ if(H5Diterate(buf, type_id, mem_space, H5VL__iod_get_query_data_cb, &udata) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to compute buffer size");
+
+ if(udata.num_elmts) {
+ buf_size = udata.num_elmts * elmt_size;
+
+ /* allocate buffer to hold data */
+ if(NULL == (*data = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate data buffer");
+
+ if(H5Dgather(space_query, buf, type_id, buf_size, *data, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_IO, H5E_CANTCOPY, FAIL, "gather failed")
+ }
+
+ *num_elmts = udata.num_elmts;
+
+done:
+ if(space_query && H5Sclose(space_query) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
+ if(mem_space && H5Sclose(mem_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
+ if(buf != NULL)
+ free(buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_get_query_data() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_read_selection
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_read_selection(iod_handle_t coh, iod_obj_id_t obj_id,
+ iod_trans_id_t rtid, hid_t space_id,
+ hid_t type_id, void *buf)
+{
+ iod_handle_t obj_oh;
+ size_t buf_size=0;
+ size_t elmt_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the array object */
+ if (iod_obj_open_read(coh, obj_id, rtid, NULL, &obj_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open array object fo read");
+
+ /* read the data selection from IOD. */
+ /* MSC - will need to do it in pieces, not it one shot. */
+ elmt_size = H5Tget_size(type_id);
+ if(H5VL__iod_server_final_io(obj_oh, space_id, elmt_size, FALSE,
+ buf, buf_size, (uint64_t)0, 0, rtid) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+done:
+ if(obj_oh.cookie != IOD_OH_UNDEFINED &&
+ iod_obj_close(obj_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_read_selection() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_attr.c b/src/H5VLiod_attr.c
new file mode 100644
index 0000000..4c4979e
--- /dev/null
+++ b/src/H5VLiod_attr.c
@@ -0,0 +1,1260 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side attribute routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_create_cb
+ *
+ * Purpose: Creates a attr as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_create_in_t *input = (attr_create_in_t *)op_data->input;
+ attr_create_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t loc_attrkv_id = input->loc_attrkv_id; /* The ID of the attribute KV of the location object*/
+ iod_obj_id_t attr_id = input->attr_id; /* The ID of the attribute that needs to be created */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV to be created */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t attr_oh, obj_oh; /* object handles */
+ iod_handle_t attr_kv_oh, mdkv_oh;
+ iod_obj_id_t obj_id;
+ const char *loc_name = input->path; /* path to start hierarchy traversal */
+ const char *attr_name = input->attr_name; /* attribute's name */
+ iod_array_struct_t array; /* IOD array structure for attribute's creation */
+ iod_size_t *max_dims; /* MAX dims for IOD */
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_size_t array_dims[H5S_MAX_RANK], current_dims[H5S_MAX_RANK];
+ iod_hint_list_t *obj_create_hint = NULL;
+ hbool_t opened_locally = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute create %s at %"PRIu64" with ID %"PRIx64" %"PRIx64"\n",
+ attr_name, loc_handle.wr_oh.cookie, attr_id, loc_attrkv_id);
+#endif
+
+ attr_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ attr_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ mdkv_oh.cookie = IOD_OH_UNDEFINED;
+ attr_kv_oh.cookie = IOD_OH_UNDEFINED;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ if(loc_handle.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ /* Try and open the starting location */
+ if (iod_obj_open_read(coh, loc_id, wtid, NULL, &loc_handle.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open start location");
+ opened_locally = TRUE;
+ }
+
+ /* Open the object where the attribute needs to be created. */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, loc_name, rtid,
+ cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* Set the IOD array creation parameters */
+ array.cell_size = (uint32_t)H5Tget_size(input->type_id);
+ array.num_dims = (uint32_t)H5Sget_simple_extent_ndims(input->space_id);
+
+ /* Handle Scalar Dataspaces (set rank and current dims size to 1) */
+ if(0 == array.num_dims) {
+ array.num_dims = 1;
+ array.firstdim_max = 1;
+ current_dims[0] = 1;
+ }
+ else {
+ if(H5Sget_simple_extent_dims(input->space_id, current_dims, array_dims) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimentions' sizes");
+ array.firstdim_max = array_dims[0];
+ }
+
+ array.current_dims = current_dims;
+ array.chunk_dims = NULL;
+
+ /* create the attribute */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_ARRAY, NULL,
+ &array, &attr_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Attribute");
+
+ if (iod_obj_open_read(coh, attr_id, wtid, NULL, &attr_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open attribute");
+ if (iod_obj_open_write(coh, attr_id, wtid, NULL, &attr_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open attribute");
+
+ /* create the metadata KV object for the attribute */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV, NULL, NULL, &mdkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = IOD_OBJ_INVALID;
+ sp[2] = IOD_OBJ_INVALID;
+ sp[3] = IOD_OBJ_INVALID;
+
+ /* set scratch pad in attribute */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+ if (iod_obj_set_scratch(attr_oh.wr_oh, wtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+ else {
+ if (iod_obj_set_scratch(attr_oh.wr_oh, wtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+
+ /* Open Metadata KV object for write */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create scratch pad");
+
+ /* insert object type metadata */
+ if(H5VL_iod_insert_object_type(mdkv_oh, wtid, H5I_ATTR, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* MSC - need to check size of datatype if it fits in
+ entry otherwise create a BLOB */
+
+ /* insert datatype metadata */
+ if(H5VL_iod_insert_datatype(mdkv_oh, wtid, input->type_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert dataspace metadata */
+ if(H5VL_iod_insert_dataspace(mdkv_oh, wtid, input->space_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* if the starting location is not the last component, need to
+ read the attrkv_id of the last object where attribute needs
+ to be created */
+ if(loc_id != obj_id || loc_attrkv_id == IOD_OBJ_INVALID) {
+ /* get scratch pad of the parent */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the attribute KV in scratch pad */
+ if (iod_obj_open_write(coh, sp[1], wtid, NULL /*hints*/, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the attribute KV */
+ if (iod_obj_open_write(coh, loc_attrkv_id, wtid, NULL /*hints*/, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ /* insert new attribute in scratch pad of current object */
+ if(H5VL_iod_insert_new_link(attr_kv_oh, wtid, attr_name,
+ H5L_TYPE_HARD, &attr_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ output.iod_oh.rd_oh.cookie = attr_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = attr_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr create, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(TRUE == opened_locally || loc_handle.rd_oh.cookie != obj_oh.rd_oh.cookie) {
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL);
+ }
+
+ iod_obj_close(mdkv_oh, NULL, NULL);
+ iod_obj_close(attr_kv_oh, NULL, NULL);
+
+ /* return an UNDEFINED oh to the client if the operation failed */
+ if(ret_value < 0) {
+ fprintf(stderr, "Failed Attribute Create\n");
+
+ if(attr_oh.rd_oh.cookie != IOD_OH_UNDEFINED &&
+ iod_obj_close(attr_oh.rd_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if(attr_oh.wr_oh.cookie != IOD_OH_UNDEFINED &&
+ iod_obj_close(attr_oh.wr_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ if(obj_create_hint) {
+ free(obj_create_hint);
+ obj_create_hint = NULL;
+ }
+
+#if 0
+ /* close the Metadata KV object */
+ if(mdkv_oh.cookie != IOD_OH_UNDEFINED &&
+ iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* close the Attribute KV object */
+ if(attr_kv_oh.cookie != IOD_OH_UNDEFINED &&
+ iod_obj_close(attr_kv_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+#endif
+
+ input = (attr_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_open_cb
+ *
+ * Purpose: Opens a attribute as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_open_in_t *input = (attr_open_in_t *)op_data->input;
+ attr_open_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start traversal */
+ iod_obj_id_t loc_id = input->loc_id; /* location ID */
+ iod_obj_id_t loc_attrkv_id = input->loc_attrkv_id; /* The ID of the attribute KV of the location object*/
+ const char *loc_name = input->path; /* current path to start traversal */
+ const char *attr_name = input->attr_name; /* attribute's name to open */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t attr_oh, obj_oh;
+ iod_handle_t attr_kv_oh, mdkv_oh;
+ iod_obj_id_t obj_id;
+ iod_obj_id_t attr_id;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ H5VL_iod_link_t iod_link;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute open %s at %s (OH %"PRIu64" ID %"PRIx64")\n",
+ attr_name, loc_name, loc_handle.rd_oh.cookie, loc_id);
+#endif
+
+ /* Open the object where the attribute needs to be opened. */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Attribute is on object (OH %"PRIu64" ID %"PRIx64")\n",
+ obj_oh.rd_oh.cookie, obj_id);
+#endif
+
+ /* if the starting location is not the last component, need to
+ read the attrkv_id of the last object where attribute needs
+ to be created */
+ if(loc_id != obj_id || loc_attrkv_id == IOD_OBJ_INVALID) {
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* if attribute KV does not exist, return error*/
+ if(IOD_OBJ_INVALID == sp[1])
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "Object has no attributes");
+
+ /* open the attribute KV in scratch pad */
+ if (iod_obj_open_read(coh, sp[1], rtid, NULL /*hints*/, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, loc_attrkv_id, rtid, NULL /*hints*/, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ /* get attribute ID */
+ if(H5VL_iod_get_metadata(attr_kv_oh, rtid, H5VL_IOD_LINK,
+ attr_name, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Attribute ID from parent KV store");
+
+ HDassert(iod_link.link_type == H5L_TYPE_HARD);
+ attr_id = iod_link.u.iod_id;
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != obj_oh.rd_oh.cookie) {
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL);
+ }
+ /* close the attribute KV holder */
+ iod_obj_close(attr_kv_oh, NULL, NULL);
+
+ /* open the attribute */
+ if (iod_obj_open_read(coh, attr_id, rtid, NULL /*hints*/, &attr_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ if (iod_obj_open_write(coh, attr_id, rtid, NULL /*hints*/, &attr_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ /* get scratch pad of the attribute */
+ if(iod_obj_get_scratch(attr_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad of the attribute */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_OBJ_DATATYPE,
+ cs_scope, NULL, &output.type_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE,
+ H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &output.space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ output.iod_id = attr_id;
+ output.mdkv_id = sp[0];
+ output.iod_oh.rd_oh.cookie = attr_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = attr_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.space_id = FAIL;
+ output.type_id = FAIL;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (attr_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_read_cb
+ *
+ * Purpose: Reads from IOD into the function shipper BDS handle.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_read_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_io_in_t *input = (attr_io_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handle_t iod_oh = input->iod_oh.rd_oh; /* attribute's object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* attribute's ID */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV */
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ //hid_t type_id = input->type_id; /* datatype ID of data */
+ hid_t space_id = input->space_id; /* dataspace of attribute */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handle_t mdkv_oh;
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ iod_mem_desc_t *mem_desc = NULL; /* memory descriptor used for reading array */
+ iod_array_iodesc_t file_desc; /* file descriptor used to read array */
+ iod_hyperslab_t hslabs; /* IOD hyperslab generated from HDF5 filespace */
+ size_t size; /* size of outgoing bulk data */
+ void *buf; /* buffer to hold outgoing data */
+ iod_checksum_t iod_cs = 0, attr_cs = 0;
+ int ndims; /* dataset's rank/number of dimensions */
+ hssize_t num_descriptors = 0; /* number of IOD file descriptors needed to describe filespace selection */
+ na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */
+ hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the attribute here or if it was already open */
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the attribute if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, iod_id, rtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Attribute Read on OH %"PRIu64" OID %"PRIx64"\n",
+ iod_oh.cookie, iod_id);
+#endif
+
+ size = HG_Bulk_handle_get_size(bulk_handle);
+
+ if(NULL == (buf = malloc(size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* Get dataspace if it is not available */
+ if(H5I_UNINIT == space_id) {
+ /* open the metadata scratch pad of the attribute */
+ if (iod_obj_open_read(coh, mdkv_id, rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE,
+ H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+ /* set the memory descriptor */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = buf;
+ mem_desc->frag[0].len = (iod_size_t)size;
+
+ num_descriptors = 1;
+
+ /* get the rank of the dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR2(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ /* handle scalar dataspace */
+ if(0 == ndims) {
+ ndims = 1;
+
+ hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t));
+
+ num_descriptors = 1;
+ hslabs.start[0] = 0;
+ hslabs.count[0] = 1;
+ hslabs.block[0] = 1;
+ hslabs.stride[0] = 1;
+ }
+ else {
+ hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+
+ /* generate the descriptor */
+ if(H5VL_iod_get_file_desc(space_id, &num_descriptors, &hslabs) < 0)
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection");
+ }
+
+ /* set the file descriptor */
+ file_desc = hslabs;
+
+ /* read from array object */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ ret = iod_array_read(iod_oh, rtid, NULL, mem_desc, &file_desc,
+ &iod_cs, NULL);
+ if(ret < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ }
+
+ attr_cs = H5_checksum_crc64(buf, size);
+
+ if(attr_cs != iod_cs)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "Data corruption detected when reading attribute");
+ }
+ else {
+ ret = iod_array_read(iod_oh, rtid, NULL, mem_desc, &file_desc, NULL, NULL);
+ if(ret < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ }
+ }
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_handle_create(buf, size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't start Mercury Bulk Data write");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "Failed to wait on Mercury Bulk data write");
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr read, sending response to client\n");
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle");
+
+ input = (attr_io_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ free(buf);
+
+ /* free allocated descriptors */
+ free(hslabs.start);
+ free(hslabs.stride);
+ free(hslabs.block);
+ free(hslabs.count);
+ if(mem_desc)
+ free(mem_desc);
+
+ /* close the attribute if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_read_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_write_cb
+ *
+ * Purpose: Writes from IOD into the function shipper BDS handle.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_write_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_io_in_t *input = (attr_io_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handle_t iod_oh = input->iod_oh.wr_oh; /* attribute's object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* attribute's ID */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV */
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ //hid_t type_id = input->type_id; /* datatype ID of data */
+ hid_t space_id = input->space_id; /* dataspace of attribute */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handle_t mdkv_oh;
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ iod_mem_desc_t *mem_desc; /* memory descriptor used for writing array */
+ iod_array_iodesc_t file_desc; /* file descriptor used to write array */
+ iod_hyperslab_t hslabs; /* IOD hyperslab generated from HDF5 filespace */
+ size_t size; /* size of outgoing bulk data */
+ void *buf; /* buffer to hold outgoing data */
+ int ndims; /* dataset's rank/number of dimensions */
+ iod_checksum_t attr_cs = 0;
+ hssize_t num_descriptors = 0; /* number of IOD file descriptors needed to describe filespace selection*/
+ na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); /* source address to pull data from */
+ hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the attribute here or if it was already opened */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the attribute if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, wtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Attribute Write on OH %"PRIu64" OID %"PRIx64"\n",
+ iod_oh.cookie, iod_id);
+#endif
+
+ /* Read bulk data here and wait for the data to be here */
+ size = HG_Bulk_handle_get_size(bulk_handle);
+ if(NULL == (buf = malloc(size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ HG_Bulk_handle_create(buf, size, HG_BULK_READWRITE, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* free the bds block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle");
+
+#if H5VL_IOD_DEBUG
+ {
+ int i;
+ int *buf_ptr = (int *)buf;
+
+ fprintf(stderr, "AWRITE Received a buffer of size %zu with values: ", size);
+ for(i=0;i<60;++i)
+ fprintf(stderr, "%d ", buf_ptr[i]);
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ /* Get dataspace if it is not available */
+ if(H5I_UNINIT == space_id) {
+ /* open the metadata scratch pad of the attribute */
+ if (iod_obj_open_read(coh, mdkv_id, wtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE, H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+ /* set the memory descriptor */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = buf;
+ mem_desc->frag[0].len = (iod_size_t)size;
+
+ num_descriptors = 1;
+
+ /* get the rank of the dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR2(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ /* handle scalar dataspace */
+ if(0 == ndims) {
+ ndims = 1;
+
+ hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t));
+
+ num_descriptors = 1;
+ hslabs.start[0] = 0;
+ hslabs.count[0] = 1;
+ hslabs.block[0] = 1;
+ hslabs.stride[0] = 1;
+ }
+ else {
+ hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+
+ /* generate the descriptor */
+ if(H5VL_iod_get_file_desc(space_id, &num_descriptors, &hslabs) < 0)
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection");
+ }
+
+ /* set the file descriptor */
+ file_desc = hslabs;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ attr_cs = H5_checksum_crc64(buf, size);
+ /* write from array object */
+ if(iod_array_write(iod_oh, wtid, NULL, mem_desc, &file_desc, &attr_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't write to array object");
+ }
+ else {
+ /* write from array object */
+ if(iod_array_write(iod_oh, wtid, NULL, mem_desc, &file_desc, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't write to array object");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr write, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+
+ input = (attr_io_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ free(buf);
+
+ /* free allocated descriptors */
+ free(hslabs.start);
+ free(hslabs.stride);
+ free(hslabs.block);
+ free(hslabs.count);
+ if(mem_desc)
+ free(mem_desc);
+
+ /* close the attribute if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_write_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_exists_cb
+ *
+ * Purpose: Checks if an attribute exists on object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_exists_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_op_in_t *input = (attr_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh; /* current object handle accessed */
+ iod_handle_t attr_kv_oh; /* KV handle holding attributes for object */
+ iod_obj_id_t obj_id;
+ const char *loc_name = input->path; /* path to start hierarchy traversal */
+ const char *attr_name = input->attr_name; /* attribute's name */
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_size_t kv_size = 0;
+ htri_t ret = -1;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute Exists %s/%s on CV %d\n", loc_name, attr_name, (int)rtid);
+#endif
+
+ /* Open the object where the attribute needs to be checked. */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, loc_name, rtid,
+ cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if(loc_id != obj_id || IOD_OBJ_INVALID == input->loc_attrkv_id) {
+ /* get scratch pad of the parent */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* if attribute KV does not exist, return false*/
+ if(IOD_OBJ_INVALID == sp[1]) {
+ ret = FALSE;
+ HGOTO_DONE(SUCCEED);
+ }
+
+ /* open the attribute KV in scratch pad */
+ if (iod_obj_open_read(coh, sp[1], rtid, NULL, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, input->loc_attrkv_id, rtid, NULL, &attr_kv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != obj_oh.rd_oh.cookie) {
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL);
+ }
+
+ /* get attribute ID */
+ if(iod_kv_get_value(attr_kv_oh, rtid, attr_name, (iod_size_t)strlen(attr_name),
+ NULL, &kv_size, NULL, NULL) < 0) {
+ ret = FALSE;
+ }
+ else {
+ ret = TRUE;
+ }
+
+ iod_obj_close(attr_kv_oh, NULL, NULL);
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr exists, sending %d to client\n", ret);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret);
+
+ input = (attr_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_exists_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_rename_cb
+ *
+ * Purpose: Renames iod HDF5 attribute.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_rename_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_rename_in_t *input = (attr_rename_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_handles_t obj_oh; /* current object handle accessed */
+ iod_handles_t attr_kv_oh; /* KV handle holding attributes for object */
+ iod_obj_id_t obj_id, attr_id;
+ const char *loc_name = input->path; /* path to start hierarchy traversal */
+ const char *old_name = input->old_attr_name;
+ const char *new_name = input->new_attr_name;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_kv_params_t kvs; /* KV lists for objects - used to unlink attribute object */
+ iod_kv_t kv; /* KV entry */
+ H5VL_iod_link_t iod_link;
+ scratch_pad sp;
+ iod_ret_t ret;
+ iod_checksum_t cs;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute Rename %s to %s\n", old_name, new_name);
+#endif
+
+ /* Open the object where the attribute needs to be checked. */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if(loc_id != obj_id || IOD_OBJ_INVALID == input->loc_attrkv_id) {
+ /* get scratch pad of the parent */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* if attribute KV does not exist, return error*/
+ if(IOD_OBJ_INVALID == sp[1])
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "Object has no attributes");
+
+ /* open the attribute KV in scratch pad */
+ if (iod_obj_open_read(coh, sp[1], wtid, NULL /*hints*/, &attr_kv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, sp[1], wtid, NULL /*hints*/, &attr_kv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, input->loc_attrkv_id, wtid, NULL /*hints*/, &attr_kv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, input->loc_attrkv_id, wtid, NULL /*hints*/, &attr_kv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != obj_oh.rd_oh.cookie) {
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL);
+ }
+
+ /* get attribute ID */
+ if(H5VL_iod_get_metadata(attr_kv_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ old_name, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Attribute ID from parent KV store");
+
+ HDassert(iod_link.link_type == H5L_TYPE_HARD);
+ attr_id = iod_link.u.iod_id;
+
+ /* remove attribute with old name */
+ kv.key = (void *)old_name;
+ kv.key_len = strlen(old_name);
+ kvs.kv = &kv;
+ kvs.cs = NULL;
+ kvs.ret = &ret;
+ if(iod_kv_unlink_keys(attr_kv_oh.wr_oh, wtid, NULL, 1, &kvs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+
+ /* insert attribute with new name */
+ if(H5VL_iod_insert_new_link(attr_kv_oh.wr_oh, wtid, new_name,
+ H5L_TYPE_HARD, &attr_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close the Attribute KV object */
+ if(iod_obj_close(attr_kv_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTFREE, FAIL, "can't close object");
+ if(iod_obj_close(attr_kv_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTFREE, FAIL, "can't close object");
+
+done:
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr rename, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (attr_rename_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_rename_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_remove_cb
+ *
+ * Purpose: Removes iod HDF5 attribute.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_remove_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_op_in_t *input = (attr_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_handles_t obj_oh; /* current object handle accessed */
+ iod_handles_t attr_kv_oh; /* KV handle holding attributes for object */
+ iod_handle_t attr_oh;
+ iod_obj_id_t obj_id, attr_id;
+ const char *loc_name = input->path; /* path to start hierarchy traversal */
+ const char *attr_name = input->attr_name; /* attribute's name */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_kv_params_t kvs;
+ iod_kv_t kv;
+ H5VL_iod_link_t iod_link;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_ret_t ret;
+ iod_checksum_t cs;
+ int step = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute Remove %s\n", attr_name);
+#endif
+
+ /* Open the object where the attribute needs to be removed. */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, loc_name, rtid,
+ cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if(loc_id != obj_id) {
+ /* get scratch pad of the parent */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* if attribute KV does not exist, return error*/
+ if(IOD_OBJ_INVALID == sp[1])
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "Object has no attributes");
+
+ /* open the attribute KV in scratch pad */
+ if (iod_obj_open_read(coh, sp[1], wtid, NULL /*hints*/, &attr_kv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, sp[1], wtid, NULL /*hints*/, &attr_kv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, input->loc_attrkv_id, wtid, NULL /*hints*/, &attr_kv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, input->loc_attrkv_id, wtid, NULL /*hints*/, &attr_kv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ step ++;
+
+ /* get attribute ID */
+ if(H5VL_iod_get_metadata(attr_kv_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ attr_name, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Attribute ID from parent KV store");
+
+ HDassert(iod_link.link_type == H5L_TYPE_HARD);
+ attr_id = iod_link.u.iod_id;
+
+ /* remove metadata KV of attribute */
+ /* open the attribute */
+ if (iod_obj_open_read(coh, attr_id, wtid, NULL /*hints*/, &attr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ step ++;
+
+ /* get scratch pad of the attribute */
+ if(iod_obj_get_scratch(attr_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ /* close the attribute oh */
+ iod_obj_close(attr_oh, NULL, NULL);
+
+ step --;
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ ret = iod_obj_unlink(coh, sp[0], wtid, NULL);
+ if(ret < 0) {
+ fprintf(stderr, "ret %d error %s\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink MDKV of attribute object");
+ }
+
+ /* remove attribute */
+ kv.key = (void *)attr_name;
+ kv.key_len = strlen(attr_name);
+ kvs.kv = &kv;
+ kvs.cs = NULL;
+ kvs.ret = &ret;
+ if(iod_kv_unlink_keys(attr_kv_oh.wr_oh, wtid, NULL, 1, &kvs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+
+ /* close the Attribute KV object */
+ iod_obj_close(attr_kv_oh.rd_oh, NULL, NULL);
+ iod_obj_close(attr_kv_oh.wr_oh, NULL, NULL);
+
+ step --;
+
+ ret = iod_obj_unlink(coh, attr_id, wtid, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "ret %d error %s\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink object");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr remove, sending response to client\n");
+#endif
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != obj_oh.rd_oh.cookie) {
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL);
+ }
+
+ if(step == 2) {
+ /* close the attribute oh */
+ iod_obj_close(attr_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ /* close the Attribute KV object */
+ iod_obj_close(attr_kv_oh.rd_oh, NULL, NULL);
+ iod_obj_close(attr_kv_oh.wr_oh, NULL, NULL);
+ step --;
+ }
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (attr_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_remove_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_close_cb
+ *
+ * Purpose: Closes iod HDF5 attribute.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_attr_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ attr_close_in_t *input = (attr_close_in_t *)op_data->input;
+ iod_handles_t iod_oh = input->iod_oh; /* iod handle to close */
+ //iod_obj_id_t iod_id = input->iod_id; /* iod id of object to close */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start attribute Close %"PRIu64" %"PRIu64"\n",
+ iod_oh.rd_oh.cookie, iod_oh.wr_oh.cookie);
+#endif
+
+ if((iod_obj_close(iod_oh.rd_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if((iod_obj_close(iod_oh.wr_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with attr close, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (attr_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_attr_close_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c
new file mode 100644
index 0000000..1940816
--- /dev/null
+++ b/src/H5VLiod_client.c
@@ -0,0 +1,3015 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ *
+ * Purpose: IOD plugin client code
+ */
+
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dpkg.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspaces */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLiod.h" /* Iod VOL plugin */
+#include "H5VLiod_common.h"
+#include "H5VLiod_client.h"
+#include "H5WBprivate.h" /* Wrapped Buffers */
+
+#ifdef H5_HAVE_EFF
+
+H5FL_EXTERN(H5VL_iod_file_t);
+H5FL_EXTERN(H5VL_iod_attr_t);
+H5FL_EXTERN(H5VL_iod_group_t);
+H5FL_EXTERN(H5VL_iod_dset_t);
+H5FL_EXTERN(H5VL_iod_dtype_t);
+
+/* H5Diterate op-data for VL traversal */
+typedef struct {
+ size_t buf_size;
+ uint8_t *buf_ptr;
+ void **off;
+ size_t *len;
+ int curr_seq;
+ size_t *str_len; /* used only for VL strings */
+} H5VL_iod_pre_write_t;
+
+static herr_t H5VL__iod_vl_map_get_finalize(size_t buf_size, void *read_buf, void *user_buf,
+ hid_t mem_type_id);
+
+herr_t
+H5VL_iod_request_decr_rc(H5VL_iod_request_t *request)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ request->ref_count --;
+
+ if(0 == request->ref_count) {
+ //request->parent_reqs = (H5VL_iod_request_t **)H5MM_xfree(request->parent_reqs);
+ request = (H5VL_iod_request_t *)H5MM_xfree(request);
+ }
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_add
+ *
+ * Purpose: Adds a request pointer to the Doubly linked list on the
+ * file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request)
+{
+ H5VL_iod_req_info_t *req_info = request->trans_info;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(request);
+
+ if (file->request_list_tail) {
+ file->request_list_tail->file_next = request;
+ request->file_prev = file->request_list_tail;
+ file->request_list_tail = request;
+ }
+ else {
+ file->request_list_head = request;
+ file->request_list_tail = request;
+ request->file_prev = NULL;
+ }
+ request->file_next = NULL;
+ file->num_req ++;
+
+ if(req_info) {
+ if (req_info->tail) {
+ req_info->tail->trans_next = request;
+ request->trans_prev = req_info->tail;
+ req_info->tail = request;
+ }
+ else {
+ req_info->head = request;
+ req_info->tail = request;
+ request->trans_prev = NULL;
+ }
+ request->trans_next = NULL;
+ req_info->num_req ++;
+
+ request->ref_count ++;
+ }
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_delete
+ *
+ * Purpose: Removes a request pointer from the Doubly linked list on the
+ * file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request)
+{
+ H5VL_iod_request_t *prev;
+ H5VL_iod_request_t *next;
+ unsigned u;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(request);
+
+ /* decrement ref count on parent requests */
+ for(u=0 ; u<request->num_parents ; u++) {
+ /* Decrement ref count on request */
+ H5VL_iod_request_decr_rc(request->parent_reqs[u]);
+ }
+
+ request->parent_reqs = (H5VL_iod_request_t **)H5MM_xfree(request->parent_reqs);
+
+ /* remove the request from the container link list */
+ prev = request->file_prev;
+ next = request->file_next;
+ if (prev) {
+ if (next) {
+ prev->file_next = next;
+ next->file_prev = prev;
+ }
+ else {
+ prev->file_next = NULL;
+ file->request_list_tail = prev;
+ }
+ }
+ else {
+ if (next) {
+ next->file_prev = NULL;
+ file->request_list_head = next;
+ }
+ else {
+ file->request_list_head = NULL;
+ file->request_list_tail = NULL;
+ }
+ }
+
+ if(request == request->obj->request)
+ request->obj->request = NULL;
+ request->file_prev = NULL;
+ request->file_next = NULL;
+
+ file->num_req --;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_wait
+ *
+ * Purpose:
+ * Waits for a particular request to complete. This will test
+ * the request completion using Mercury's test routine. If the
+ * request is still pending we test for completion of other requests in
+ * the file's linked list to try and keep making progress. Once the
+ * original requests completes, we remove it from the linked list
+ * and return.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request)
+{
+ H5VL_iod_request_t *cur_req = file->request_list_head;
+ int ret;
+ hg_status_t status;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(request);
+ HDassert(request->req);
+
+ /* Loop to complete the request while poking through other requests on the
+ container to avoid deadlock. */
+ while(1) {
+ HDassert(request->state == H5VL_IOD_PENDING);
+ /* test the operation status */
+ ret = HG_Wait(*((hg_request_t *)request->req), 0, &status);
+ if(HG_FAIL == ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to wait on request\n");
+ request->status = H5ES_STATUS_FAIL;
+ request->state = H5VL_IOD_COMPLETED;
+ H5VL_iod_request_delete(file, request);
+ break;
+ }
+ else {
+ if(status) {
+ request->status = H5ES_STATUS_SUCCEED;
+ request->state = H5VL_IOD_COMPLETED;
+ }
+ }
+
+ /* if it has not completed, go through the list of requests on the container to
+ test progress */
+ if(!status) {
+ H5VL_iod_request_t *tmp_req = NULL;
+
+ if(cur_req) {
+ if(HG_FILE_CLOSE != cur_req->type && cur_req->req != request->req) {
+ hg_status_t tmp_status;
+
+ tmp_req = cur_req->file_next;
+
+ HDassert(cur_req->state == H5VL_IOD_PENDING);
+ ret = HG_Wait(*((hg_request_t *)cur_req->req), 0, &tmp_status);
+ if(HG_FAIL == ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to wait on request\n");
+ cur_req->status = H5ES_STATUS_FAIL;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ H5VL_iod_request_delete(file, cur_req);
+ }
+ else {
+ if(tmp_status) {
+ cur_req->status = H5ES_STATUS_SUCCEED;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ if(H5VL_iod_request_complete(file, cur_req) < 0) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Operation %"PRIu64" Failed!\n", cur_req->axe_id);
+ }
+ }
+ }
+ }
+ /* next time, test the next request in the list */
+ cur_req = tmp_req;
+ }
+ }
+ /* request complete, remove it from list & break */
+ else {
+ if(H5VL_iod_request_complete(file, request) < 0) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Operation %"PRIu64" Failed!\n", request->axe_id);
+ }
+ break;
+ }
+ }
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_wait */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_wait_all
+ *
+ * Purpose: Wait and complete all the requests in the linked list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_wait_all(H5VL_iod_file_t *file)
+{
+ H5VL_iod_request_t *cur_req = file->request_list_head;
+ hg_status_t status;
+ int ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Loop to complete all requests */
+ while(cur_req) {
+ H5VL_iod_request_t *tmp_req = NULL;
+
+ tmp_req = cur_req->file_next;
+
+ HDassert(cur_req->state == H5VL_IOD_PENDING);
+ ret = HG_Wait(*((hg_request_t *)cur_req->req), HG_MAX_IDLE_TIME, &status);
+ if(HG_FAIL == ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to wait on request\n");
+ cur_req->status = H5ES_STATUS_FAIL;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ if(!status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Wait timeout reached\n");
+ cur_req->status = H5ES_STATUS_FAIL;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ H5VL_iod_request_delete(file, cur_req);
+ goto done;
+ }
+ else {
+ cur_req->status = H5ES_STATUS_SUCCEED;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ }
+ }
+
+ if(H5VL_iod_request_complete(file, cur_req) < 0)
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Operation %"PRIu64" Failed!\n", cur_req->axe_id);
+
+ cur_req = tmp_req;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_request_wait_all */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_wait_some
+ *
+ * Purpose: Wait for some requests on the linked list, particularly
+ * the ones that are tracked with a particular object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object)
+{
+ H5VL_iod_request_t *cur_req = file->request_list_head;
+ hg_status_t status;
+ int ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Loop to complete some requests */
+ while(cur_req) {
+ H5VL_iod_request_t *tmp_req;
+
+ tmp_req = cur_req->file_next;
+
+ /* If the request is pending on the object we want, complete it */
+ if(cur_req->obj == object &&
+ cur_req->state == H5VL_IOD_PENDING) {
+ ret = HG_Wait(*((hg_request_t *)cur_req->req), HG_MAX_IDLE_TIME,
+ &status);
+ if(HG_FAIL == ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to wait on request\n");
+ cur_req->status = H5ES_STATUS_FAIL;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ H5VL_iod_request_delete(file, cur_req);
+ }
+ else {
+ if(!status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Wait timeout reached\n");
+ cur_req->status = H5ES_STATUS_FAIL;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ H5VL_iod_request_delete(file, cur_req);
+ }
+ else {
+ cur_req->status = H5ES_STATUS_SUCCEED;
+ cur_req->state = H5VL_IOD_COMPLETED;
+ if(H5VL_iod_request_complete(file, cur_req) < 0)
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Operation %"PRIu64" Failed!\n", cur_req->axe_id);
+ }
+ }
+ }
+ cur_req = tmp_req;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_request_wait_some */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_complete
+ *
+ * Purpose: Completion calls for every type of request. This checks
+ * the return status from the server, and frees memory
+ * allocated by this request.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(req->state == H5VL_IOD_COMPLETED);
+
+ switch(req->type) {
+ case HG_ANALYSIS_EXECUTE:
+ {
+ analysis_execute_out_t *output = (analysis_execute_out_t *)req->data;
+
+ if(SUCCEED != output->ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Analysis Execute failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ free(output);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_FILE_CREATE:
+ if(IOD_OH_UNDEFINED == req->obj->file->remote_file.coh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to create file\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ MPI_Barrier (file->comm);
+ H5VL_iod_request_delete(file, req);
+ break;
+ case HG_FILE_OPEN:
+ if(IOD_OH_UNDEFINED == req->obj->file->remote_file.coh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open file\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ hid_t rcxt_id;
+
+ if(NULL == (plist = H5P_object_verify(file->fapl_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ /* determine if we want to update the latest readable version
+ when the file is opened */
+ if(H5P_get(plist, H5VL_ACQUIRE_RC_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for rxct id");
+
+ if(FAIL != rcxt_id) {
+ H5RC_t *rc = NULL;
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ rc->c_version = file->remote_file.c_version;
+ rc->file = file;
+ }
+
+ /* increment ref count on ID generated by Mercury encoding callback */
+ if(H5I_inc_ref(req->obj->file->remote_file.fcpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ case HG_ATTR_CREATE:
+ {
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == attr->remote_attr.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to create Attribute\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_OPEN:
+ {
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == attr->remote_attr.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Attribute\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(attr->remote_attr.type_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(attr->remote_attr.space_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_GROUP_CREATE:
+ {
+ H5VL_iod_group_t *group = (H5VL_iod_group_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == group->remote_group.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to create Group\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_GROUP_OPEN:
+ {
+ H5VL_iod_group_t *group = (H5VL_iod_group_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == group->remote_group.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Group\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(group->remote_group.gcpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_CREATE:
+ {
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == map->remote_map.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to create Map\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_OPEN:
+ {
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == map->remote_map.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Map\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(map->remote_map.mcpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(map->remote_map.keytype_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(map->remote_map.valtype_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_CREATE:
+ {
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == dset->remote_dset.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to create Dataset\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_OPEN:
+ {
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == dset->remote_dset.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Dataset\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(dset->remote_dset.dcpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(dset->remote_dset.type_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(dset->remote_dset.space_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DTYPE_COMMIT:
+ {
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == dtype->remote_dtype.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to commit Datatype\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DTYPE_OPEN:
+ {
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)req->obj;
+
+ if(IOD_OH_UNDEFINED == dtype->remote_dtype.iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Datatype\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(dtype->remote_dtype.tcpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(H5I_inc_ref(dtype->remote_dtype.type_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_WRITE:
+ {
+ H5VL_iod_write_info_t *info = (H5VL_iod_write_info_t *)req->data;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free dataset bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ if(*info->vl_len_bulk_handle != HG_BULK_NULL &&
+ HG_SUCCESS != HG_Bulk_handle_free(*info->vl_len_bulk_handle)) {
+ fprintf(stderr, "failed to free dataset bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ if(SUCCEED != *((int *)info->status)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Errrr! Dataset Write Failure Reported from Server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ if(info->vl_segments) {
+ free(info->vl_segments);
+ info->vl_segments = NULL;
+ }
+ if(info->vl_lengths) {
+ free(info->vl_lengths);
+ info->vl_lengths = NULL;
+ }
+
+ free(info->status);
+ info->status = NULL;
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info->vl_len_bulk_handle = (hg_bulk_t *)H5MM_xfree(info->vl_len_bulk_handle);
+ info = (H5VL_iod_write_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_READ:
+ {
+ H5VL_iod_read_info_t *info = (H5VL_iod_read_info_t *)req->data;
+ H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free dataset bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ if(SUCCEED != read_status->ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Errrrr! Dataset Read Failure Reported from Server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ uint32_t raw_cs_scope = info->raw_cs_scope;
+
+ if(raw_cs_scope) {
+ uint64_t internal_cs = 0;
+
+ /* calculate a checksum for the data recieved */
+ internal_cs = H5S_checksum(info->buf_ptr, info->type_size,
+ (size_t)info->nelmts, info->space);
+
+ /* verify data integrity */
+ if((raw_cs_scope & H5_CHECKSUM_TRANSFER) &&
+ internal_cs != read_status->cs) {
+ HERROR(H5E_FUNC, H5E_CANTINIT,
+ "Errrrr! Dataset Read integrity failure (expecting %"PRIu64" got %"PRIu64").\n",
+ read_status->cs, internal_cs);
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+#if H5VL_IOD_DEBUG
+ if(!raw_cs_scope & H5_CHECKSUM_TRANSFER) {
+ printf("NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA READ\n");
+ }
+#endif
+
+ /* If the app gave us a buffer to store the checksum, then put it there */
+ if(info->cs_ptr)
+ *info->cs_ptr = internal_cs;
+ }
+ }
+
+ H5VL_iod_type_info_reset(info->type_info);
+ info->type_info = (H5VL_iod_type_info_t *)H5MM_xfree(info->type_info);
+ if(info->space && H5S_close(info->space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ read_status = (H5VL_iod_read_status_t *)H5MM_xfree(read_status);
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_read_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_GET_VL_SIZE:
+ {
+ H5VL_iod_read_info_t *info = (H5VL_iod_read_info_t *)req->data;
+ H5VL_iod_read_status_t *status = (H5VL_iod_read_status_t *)info->status;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle) ||
+ SUCCEED != status->ret) {
+
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Errrrr! Dataset Read Failure Reported from Server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+
+ if(H5Sclose(info->file_space_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ if(H5Tclose(info->mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Pclose(info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to release plist");
+ if(info->space && H5S_close(info->space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ status = (H5VL_iod_read_status_t *)H5MM_xfree(status);
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_read_info_t *)H5MM_xfree(info);
+ }
+ else {
+ dset_io_in_t input;
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+ hid_t rcxt_id;
+ H5RC_t *rc;
+ H5P_genplist_t *plist = NULL;
+ hg_bulk_segment_t *segments = NULL;
+ size_t num_segments = 0;
+ hg_request_t hg_req;
+ hg_status_t hg_status;
+
+ /* MSC - Need to fix this to allow for nested VLs */
+ HDassert(info->vl_lengths_size == status->buf_size);
+
+ /* Create segments from vl lengths */
+ if(H5VL_iod_create_segments_recv((char *)info->buf_ptr, info->type_info,
+ (size_t)info->nelmts, &segments, &num_segments,
+ info->vl_lengths, info->vl_lengths_size,
+ NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create segments for bulk data transfer");
+ HDassert(segments);
+
+ /* Register non-contiguous memory segments */
+ if(HG_SUCCESS != HG_Bulk_handle_create_segments(segments, num_segments,
+ HG_BULK_READWRITE,
+ info->bulk_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data handle");
+
+ /* get the context ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(info->dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_CONTEXT_ID, &rcxt_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for trans_id");
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ /* Fill input structure for reading data */
+ input.coh = file->remote_file.coh;
+ input.iod_oh = dset->remote_dset.iod_oh;
+ input.iod_id = dset->remote_dset.iod_id;
+ input.mdkv_id = dset->remote_dset.mdkv_id;
+ input.bulk_handle = *info->bulk_handle;
+ input.vl_len_bulk_handle = HG_BULK_NULL;
+ input.checksum = 0;
+ input.dxpl_id = info->dxpl_id;
+ input.space_id = info->file_space_id;
+ input.mem_type_id = info->mem_type_id;
+ input.dset_type_id = dset->remote_dset.type_id;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = dset->common.file->md_integrity_scope;
+ input.trans_num = 0;
+ input.axe_id = info->axe_id + 1;
+ input.axe_info.axe_id = info->axe_id;
+ input.axe_info.start_range = 0;
+ input.axe_info.count = 0;
+ input.axe_info.num_parents = 0;
+ input.axe_info.parent_axe_ids = NULL;
+
+ /* forward the call to the ION */
+ if(HG_Forward(info->ion_target, info->read_id, &input, info->status, &hg_req) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship operation");
+
+ if(HG_FAIL == HG_Wait(hg_req, HG_MAX_IDLE_TIME, &hg_status)) {
+ fprintf(stderr, "failed to wait on request\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ HG_Request_free(hg_req);
+ HG_Bulk_handle_free(*info->bulk_handle);
+
+ if(segments) {
+ free(segments);
+ segments = NULL;
+ }
+ }
+
+ if(info->vl_lengths) {
+ HDfree(info->vl_lengths);
+ info->vl_lengths = NULL;
+ }
+ if(H5Sclose(info->file_space_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ if(H5Tclose(info->mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Pclose(info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to release plist");
+ H5VL_iod_type_info_reset(info->type_info);
+ info->type_info = (H5VL_iod_type_info_t *)H5MM_xfree(info->type_info);
+ if(info->space && H5S_close(info->space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ status = (H5VL_iod_read_status_t *)H5MM_xfree(status);
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_read_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_WRITE:
+ case HG_ATTR_READ:
+ {
+ H5VL_iod_attr_io_info_t *info = (H5VL_iod_attr_io_info_t *)req->data;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free attribute bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ if(SUCCEED != *((int *)info->status)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Attribute I/O Failure Reported from Server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ HDfree(info->status);
+ info->status = NULL;
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_attr_io_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_SET:
+ {
+ H5VL_iod_map_set_info_t *info = (H5VL_iod_map_set_info_t *)req->data;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->value_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free Map Value bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ if(SUCCEED != *((int *)info->status)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Errrr! MAP set Failure Reported from Server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(info->status);
+ info->status = NULL;
+ info->value_handle = (hg_bulk_t *)H5MM_xfree(info->value_handle);
+ info = (H5VL_iod_map_set_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_DELETE:
+ {
+ int *status = (int *)req->data;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "MAP delete failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_GET:
+ {
+ H5VL_iod_map_io_info_t *info = (H5VL_iod_map_io_info_t *)req->data;
+ map_get_out_t *output = info->output;
+
+ if(SUCCEED != output->ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "MAP get failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+
+ /* free stuff associated with request */
+ info->value_handle = (hg_bulk_t *)H5MM_xfree(info->value_handle);
+ if(H5Tclose(info->val_mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Tclose(info->key_mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Pclose(info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to release plist");
+
+ free(info->output);
+ info->output = NULL;
+ info = (H5VL_iod_map_io_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+
+ /* remove request from file list */
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ else {
+ /* If the data is not VL, then just free resources and
+ remove the request */
+ if(!info->val_is_vl) {
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->value_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free value bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ uint64_t internal_cs = 0;
+ uint32_t raw_cs_scope = info->raw_cs_scope;
+
+ /* calculate a checksum for the data recieved */
+ internal_cs = H5_checksum_crc64(info->val_ptr, info->val_size);
+
+ /* verify data integrity */
+ if((raw_cs_scope & H5_CHECKSUM_TRANSFER) &&
+ internal_cs != output->val_cs) {
+ HERROR(H5E_FUNC, H5E_CANTINIT,
+ "Errrrr! MAP Get integrity failure (expecting %"PRIu64" got %"PRIu64").\n",
+ output->val_cs, internal_cs);
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+#if H5VL_IOD_DEBUG
+ if(!raw_cs_scope & H5_CHECKSUM_TRANSFER) {
+ printf("NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA READ\n");
+ }
+#endif
+ /* If the app gave us a buffer to store the checksum, then put it there */
+ if(info->val_cs_ptr)
+ *info->val_cs_ptr = internal_cs;
+ }
+
+ free(info->output);
+ info->output = NULL;
+ info->value_handle = (hg_bulk_t *)H5MM_xfree(info->value_handle);
+ info = (H5VL_iod_map_io_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ else {
+ /* If this is the second roundtrip with the VL
+ data, scatter it in the user buffer */
+ if(info->val_size && output->val_size) {
+ HDassert(info->val_size == output->val_size);
+
+ /* scatter the data into the user's buffer */
+ if(H5VL__iod_vl_map_get_finalize(output->val_size,
+ info->read_buf,
+ (void *)info->val_ptr,
+ info->val_mem_type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to store VL data in user buffer");
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ /* if the data is VL, then we need to submit another
+ get operation this time to get the actual data */
+ else {
+ void *value_buf = NULL;
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj;
+ map_get_in_t input;
+ H5RC_t *rc = NULL;
+ H5VL_iod_map_io_info_t vl_read_info;
+
+ /* get the RC object */
+ if(NULL == (rc = (H5RC_t *)H5I_object_verify(info->rcxt_id, H5I_RC)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a READ CONTEXT ID");
+
+ if(NULL == (value_buf = (void *)HDmalloc(output->val_size)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate VL recieve buffer");
+
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(value_buf, output->val_size,
+ HG_BULK_READWRITE, info->value_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+
+ /* Fill input structure */
+ input.coh = file->remote_file.coh;
+ input.iod_oh = map->remote_map.iod_oh;
+ input.iod_id = map->remote_map.iod_id;
+ input.dxpl_id = info->dxpl_id;
+ input.key_memtype_id = info->key_mem_type_id;
+ input.key_maptype_id = map->remote_map.keytype_id;
+ input.val_memtype_id = info->val_mem_type_id;
+ input.val_maptype_id = map->remote_map.valtype_id;
+ input.key.buf_size = info->key.buf_size;
+ input.key.buf = info->key.buf;
+ input.val_is_vl = TRUE;
+ input.val_size = output->val_size;
+ input.val_handle = *info->value_handle;
+ input.rcxt_num = rc->c_version;
+ input.cs_scope = map->common.file->md_integrity_scope;
+
+ vl_read_info.output = output;
+ vl_read_info.value_handle = info->value_handle;
+ vl_read_info.val_is_vl = TRUE;
+ vl_read_info.val_ptr = info->val_ptr;
+ vl_read_info.val_mem_type_id = info->val_mem_type_id;
+ vl_read_info.val_size = input.val_size;
+ vl_read_info.read_buf = value_buf;
+
+ /* remove request from file list */
+ H5VL_iod_request_delete(file, req);
+
+ if(H5VL__iod_create_and_forward(info->map_get_id, HG_MAP_GET,
+ (H5VL_iod_object_t *)map, 0,
+ 0, NULL, (H5VL_iod_req_info_t *)rc,
+ &input, output, &vl_read_info, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to create and ship map get");
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->value_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free value bulk handle\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ /* free stuff associated with request */
+ info->value_handle = (hg_bulk_t *)H5MM_xfree(info->value_handle);
+ HDfree(value_buf);
+ if(H5Tclose(info->val_mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Tclose(info->key_mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Pclose(info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to release plist");
+
+ free(info->output);
+ info->output = NULL;
+ info = (H5VL_iod_map_io_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ break;
+ }
+ }
+ }
+ }
+ case HG_MAP_GET_COUNT:
+ {
+ hsize_t *count = (hsize_t *)req->data;
+
+ if(*count == IOD_COUNT_UNDEFINED) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "MAP get_count failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_EXISTS:
+ {
+ H5VL_iod_exists_info_t *info = (H5VL_iod_exists_info_t *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ if(info->server_ret < 0) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "MAP exists failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else if (0 == info->server_ret)
+ *info->user_bool = FALSE;
+ else
+ *info->user_bool = TRUE;
+
+ req->data = NULL;
+ obj->request = NULL;
+ info = (H5VL_iod_exists_info_t *)H5MM_xfree(info);
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_FILE_CLOSE:
+ {
+ int *status = (int *)req->data;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "FILE close failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ if(0 == file->my_rank)
+ MPI_Barrier (file->comm);
+
+ free(status);
+ req->data = NULL;
+ file->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free everything */
+ free(file->file_name);
+ free(file->common.obj_name);
+ if(H5FD_mpi_comm_info_free(&file->comm, &file->info) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "Communicator/Info free failed");
+ if(file->common.comment)
+ HDfree(file->common.comment);
+ if(file->fapl_id != H5P_FILE_ACCESS_DEFAULT && H5Pclose(file->fapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(file->remote_file.fcpl_id != H5P_FILE_CREATE_DEFAULT &&
+ H5Pclose(file->remote_file.fcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ file = H5FL_FREE(H5VL_iod_file_t, file);
+ break;
+ }
+ case HG_ATTR_RENAME:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "ATTR rename failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ obj->request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_REMOVE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "ATTR remove failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ obj->request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_EXISTS:
+ case HG_LINK_EXISTS:
+ case HG_OBJECT_EXISTS:
+ {
+ htri_t *ret = (htri_t *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ if(*ret < 0) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "EXIST OP failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ obj->request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "ATTR close failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ attr->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free attr components */
+ if(attr->common.obj_name)
+ free(attr->common.obj_name);
+ if(attr->loc_name)
+ free(attr->loc_name);
+ if(attr->common.comment)
+ HDfree(attr->common.comment);
+ if(H5Tclose(attr->remote_attr.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(H5Sclose(attr->remote_attr.space_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace");
+ attr = H5FL_FREE(H5VL_iod_attr_t, attr);
+ break;
+ }
+ case HG_GROUP_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_group_t *grp = (H5VL_iod_group_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "GROUP CLOSE failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ grp->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free group components */
+ if(grp->common.obj_name)
+ free(grp->common.obj_name);
+ if(grp->common.comment)
+ HDfree(grp->common.comment);
+ if(grp->gapl_id != H5P_GROUP_ACCESS_DEFAULT && H5Pclose(grp->gapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != H5P_GROUP_CREATE_DEFAULT &&
+ H5Pclose(grp->remote_group.gcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ break;
+ }
+ case HG_DSET_SET_EXTENT:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "DATASET set extent failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ dset->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "DATASET %s CLOSE failed at the server\n",
+ dset->common.obj_name);
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ /* free dset components */
+ if(dset->common.obj_name)
+ free(dset->common.obj_name);
+ if(dset->common.comment)
+ HDfree(dset->common.comment);
+ if(H5Tclose(dset->remote_dset.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(H5Sclose(dset->remote_dset.space_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace");
+ if(dset->remote_dset.dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
+ if(H5Pclose(dset->remote_dset.dcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ }
+ if(dset->dapl_id != H5P_DATASET_ACCESS_DEFAULT) {
+ if(H5Pclose(dset->dapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ }
+
+ free(status);
+ req->data = NULL;
+ dset->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ break;
+ }
+ case HG_MAP_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj;
+
+ if(H5VL_iod_request_wait_some(map->common.file, map) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on all object requests");
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "MAP close failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ map->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free map components */
+ if(map->common.obj_name)
+ free(map->common.obj_name);
+ if(map->common.comment)
+ HDfree(map->common.comment);
+ if(H5Tclose(map->remote_map.keytype_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(H5Tclose(map->remote_map.valtype_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ break;
+ }
+ case HG_DTYPE_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)req->obj;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "datatype close failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ dtype->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free dtype components */
+ if(dtype->common.obj_name)
+ free(dtype->common.obj_name);
+ if(dtype->common.comment)
+ HDfree(dtype->common.comment);
+ if(dtype->remote_dtype.tcpl_id != H5P_DATATYPE_CREATE_DEFAULT &&
+ H5Pclose(dtype->remote_dtype.tcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(dtype->tapl_id != H5P_DATATYPE_ACCESS_DEFAULT &&
+ H5Pclose(dtype->tapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(H5Tclose(dtype->remote_dtype.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ break;
+ }
+ case HG_LINK_CREATE:
+ case HG_LINK_MOVE:
+ case HG_LINK_REMOVE:
+ case HG_OBJECT_SET_COMMENT:
+ case HG_OBJECT_COPY:
+ {
+ int *status = (int *)req->data;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Link operation failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_LINK_GET_INFO:
+ {
+ H5L_ff_info_t *linfo = (H5L_ff_info_t *)req->data;
+
+ if(linfo->type == H5L_TYPE_ERROR) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Link get_info failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_OBJECT_GET_INFO:
+ {
+ H5O_ff_info_t *oinfo = (H5O_ff_info_t *)req->data;
+
+ if(oinfo->type == H5O_TYPE_UNKNOWN) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "OBJECT get_info failed at the server\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_LINK_GET_VAL:
+ {
+ link_get_val_out_t *result = (link_get_val_out_t *)req->data;
+
+ if(SUCCEED != result->ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "get comment failed\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ /* Free Mercury request */
+ if(HG_Request_free(*((hg_request_t *)req->req)) != HG_SUCCESS)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+
+ free(result);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ HGOTO_DONE(ret_value);
+ //break;
+ }
+ case HG_OBJECT_OPEN_BY_TOKEN:
+ {
+ iod_handles_t *oh = (iod_handles_t *)req->data;
+
+ if(IOD_OH_UNDEFINED == (*oh).rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to Open object by token\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_OBJECT_OPEN:
+ {
+ H5VL_iod_remote_object_t *obj = (H5VL_iod_remote_object_t *)req->data;
+
+ if(IOD_OH_UNDEFINED == obj->iod_oh.rd_oh.cookie) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to open Object\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+ else {
+ /* increment ref count on IDs generated by Mercury encoding callback */
+ if(H5I_inc_ref(obj->cpl_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ if(FAIL != obj->id1) {
+ if(H5I_inc_ref(obj->id1, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+ if(FAIL != obj->id2) {
+ if(H5I_inc_ref(obj->id2, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count");
+ }
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_OBJECT_GET_COMMENT:
+ {
+ object_get_comment_out_t *result = (object_get_comment_out_t *)req->data;
+
+ if(SUCCEED != result->ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "get comment failed\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ /* Free Mercury request */
+ if(HG_Request_free(*((hg_request_t *)req->req)) != HG_SUCCESS)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+
+ free(result);
+ H5VL_iod_request_delete(file, req);
+ HGOTO_DONE(ret_value);
+ //break;
+ }
+ case HG_RC_ACQUIRE:
+ {
+ H5VL_iod_rc_info_t *rc_info = (H5VL_iod_rc_info_t *)req->data;
+
+ if(SUCCEED != rc_info->result.ret) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Failed to Acquire Read Context %"PRIu64"\n", *(rc_info->c_version_ptr));
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ rc_info->read_cxt->c_version = rc_info->result.c_version;
+ *rc_info->c_version_ptr = rc_info->result.c_version;
+ rc_info->read_cxt->req_info.request = NULL;
+ rc_info = (H5VL_iod_rc_info_t *)H5MM_xfree(rc_info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_RC_RELEASE:
+ case HG_RC_PERSIST:
+ case HG_RC_SNAPSHOT:
+ {
+ int *status = (int *)req->data;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Failed to Read Context OP\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_TR_START:
+ {
+ H5VL_iod_tr_info_t *tr_info = (H5VL_iod_tr_info_t *)req->data;
+
+ if(SUCCEED != tr_info->result) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Failed to start transaction %"PRIu64"\n", tr_info->tr->trans_num);
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ tr_info->tr->req_info.request = NULL;
+ tr_info = (H5VL_iod_tr_info_t *)H5MM_xfree(tr_info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_TR_FINISH:
+ case HG_TR_SET_DEPEND:
+ case HG_TR_SKIP:
+ case HG_TR_ABORT:
+ case HG_EVICT:
+ {
+ int *status = (int *)req->data;
+
+ if(SUCCEED != *status) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Failed transaction OP\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_PREFETCH:
+ {
+ hrpl_t *replica_id = (hrpl_t *)req->data;
+
+ if(0 == *replica_id) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "Failed transaction OP\n");
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ }
+
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_LINK_ITERATE:
+ case HG_OBJECT_VISIT:
+ case HG_MAP_ITERATE:
+ default:
+ req->status = H5ES_STATUS_FAIL;
+ req->state = H5VL_IOD_COMPLETED;
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Request Type not supported");
+ }
+
+ /* Free Mercury request */
+ if(HG_Request_free(*((hg_request_t *)req->req)) != HG_SUCCESS)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_request_complete */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_request_cancel
+ *
+ * Purpose: Cancels a particular request by freeing memory
+ * associated with it.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(req->state == H5VL_IOD_CANCELLED);
+
+ switch(req->type) {
+ case HG_ANALYSIS_EXECUTE:
+ {
+ analysis_execute_out_t *output = (analysis_execute_out_t *)req->data;
+
+ free(output);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_WRITE:
+ {
+ H5VL_iod_write_info_t *info = (H5VL_iod_write_info_t *)req->data;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle)) {
+ fprintf(stderr, "failed to free bulk handle\n");
+ }
+
+ if(info->vl_segments) {
+ HDfree(info->vl_segments);
+ info->vl_segments = NULL;
+ }
+ if(info->vl_lengths) {
+ HDfree(info->vl_lengths);
+ info->vl_lengths = NULL;
+ }
+
+ HDfree(info->status);
+ info->status = NULL;
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info->vl_len_bulk_handle = (hg_bulk_t *)H5MM_xfree(info->vl_len_bulk_handle);
+ info = (H5VL_iod_write_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_GET_VL_SIZE:
+ {
+ H5VL_iod_read_info_t *info = (H5VL_iod_read_info_t *)req->data;
+
+ if(H5Sclose(info->file_space_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ if(H5Tclose(info->mem_type_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release datatype");
+ if(H5Pclose(info->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to release plist");
+ }
+ case HG_DSET_READ:
+ {
+ H5VL_iod_read_info_t *info = (H5VL_iod_read_info_t *)req->data;
+
+ /* Free memory handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(*info->bulk_handle)) {
+ HERROR(H5E_FUNC, H5E_CANTINIT, "failed to free bulk handle\n");
+ }
+
+ H5VL_iod_type_info_reset(info->type_info);
+ info->type_info = (H5VL_iod_type_info_t *)H5MM_xfree(info->type_info);
+ if(info->space && H5S_close(info->space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace");
+ info->status = (H5VL_iod_read_status_t *)H5MM_xfree(info->status);
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_read_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_WRITE:
+ case HG_ATTR_READ:
+ {
+ H5VL_iod_attr_io_info_t *info = (H5VL_iod_attr_io_info_t *)req->data;
+
+ HDfree(info->status);
+ info->status = NULL;
+ info->bulk_handle = (hg_bulk_t *)H5MM_xfree(info->bulk_handle);
+ info = (H5VL_iod_attr_io_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_FILE_CREATE:
+ case HG_FILE_OPEN:
+ case HG_FILE_CLOSE:
+ {
+ int *status = (int *)req->data;
+
+ free(status);
+ req->data = NULL;
+ file->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free everything */
+ free(file->file_name);
+ free(file->common.obj_name);
+ if(H5FD_mpi_comm_info_free(&file->comm, &file->info) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "Communicator/Info free failed");
+ if(file->common.comment)
+ HDfree(file->common.comment);
+ if(file->fapl_id != H5P_FILE_ACCESS_DEFAULT && H5Pclose(file->fapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(file->remote_file.fcpl_id != 0 &&
+ file->remote_file.fcpl_id != H5P_FILE_CREATE_DEFAULT &&
+ H5Pclose(file->remote_file.fcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ file = H5FL_FREE(H5VL_iod_file_t, file);
+ break;
+ }
+ case HG_ATTR_REMOVE:
+ case HG_ATTR_RENAME:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ obj->request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_EXISTS:
+ {
+ H5VL_iod_exists_info_t *info = (H5VL_iod_exists_info_t *)req->data;
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ req->data = NULL;
+ obj->request = NULL;
+ info = (H5VL_iod_exists_info_t *)H5MM_xfree(info);
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_EXISTS:
+ case HG_LINK_EXISTS:
+ case HG_OBJECT_EXISTS:
+ case HG_MAP_GET_COUNT:
+ {
+ H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj;
+
+ req->data = NULL;
+ obj->request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_ATTR_CREATE:
+ case HG_ATTR_OPEN:
+ case HG_ATTR_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_attr_t *attr = (H5VL_iod_attr_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ attr->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free attr components */
+ if(attr->common.obj_name)
+ free(attr->common.obj_name);
+ if(attr->loc_name)
+ free(attr->loc_name);
+ if(attr->common.comment)
+ HDfree(attr->common.comment);
+ if(attr->remote_attr.type_id != 0 &&
+ H5Tclose(attr->remote_attr.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(attr->remote_attr.space_id != 0 &&
+ H5Sclose(attr->remote_attr.space_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace");
+ attr = H5FL_FREE(H5VL_iod_attr_t, attr);
+ break;
+ }
+ case HG_GROUP_CREATE:
+ case HG_GROUP_OPEN:
+ case HG_GROUP_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_group_t *grp = (H5VL_iod_group_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ grp->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free group components */
+ if(grp->common.obj_name)
+ free(grp->common.obj_name);
+ if(grp->common.comment)
+ HDfree(grp->common.comment);
+ if(grp->gapl_id != H5P_GROUP_ACCESS_DEFAULT && H5Pclose(grp->gapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(grp->remote_group.gcpl_id != 0 &&
+ grp->remote_group.gcpl_id != H5P_GROUP_CREATE_DEFAULT &&
+ H5Pclose(grp->remote_group.gcpl_id) < 0) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ }
+ grp = H5FL_FREE(H5VL_iod_group_t, grp);
+ break;
+ }
+ case HG_DSET_SET_EXTENT:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ dset->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_DSET_CREATE:
+ case HG_DSET_OPEN:
+ case HG_DSET_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ dset->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free dset components */
+ if(dset->common.obj_name)
+ free(dset->common.obj_name);
+ if(dset->common.comment)
+ HDfree(dset->common.comment);
+ if(dset->remote_dset.dcpl_id != 0 &&
+ dset->remote_dset.dcpl_id != H5P_DATASET_CREATE_DEFAULT &&
+ H5Pclose(dset->remote_dset.dcpl_id) < 0) {
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ }
+ if(dset->dapl_id != H5P_DATASET_ACCESS_DEFAULT &&
+ H5Pclose(dset->dapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(dset->remote_dset.type_id != 0 &&
+ H5Tclose(dset->remote_dset.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(dset->remote_dset.space_id != 0 &&
+ H5Sclose(dset->remote_dset.space_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace");
+ dset = H5FL_FREE(H5VL_iod_dset_t, dset);
+ break;
+ }
+ case HG_MAP_CREATE:
+ case HG_MAP_OPEN:
+ case HG_MAP_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ map->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free map components */
+ if(map->common.obj_name)
+ free(map->common.obj_name);
+ if(map->common.comment)
+ HDfree(map->common.comment);
+ if(H5Tclose(map->remote_map.keytype_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ if(H5Tclose(map->remote_map.valtype_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ map = H5FL_FREE(H5VL_iod_map_t, map);
+ break;
+ }
+ case HG_DTYPE_COMMIT:
+ case HG_DTYPE_OPEN:
+ case HG_DTYPE_CLOSE:
+ {
+ int *status = (int *)req->data;
+ H5VL_iod_dtype_t *dtype = (H5VL_iod_dtype_t *)req->obj;
+
+ free(status);
+ req->data = NULL;
+ dtype->common.request = NULL;
+ H5VL_iod_request_delete(file, req);
+
+ /* free dtype components */
+ if(dtype->common.obj_name)
+ free(dtype->common.obj_name);
+ if(dtype->common.comment)
+ HDfree(dtype->common.comment);
+ if(dtype->remote_dtype.tcpl_id != 0 &&
+ dtype->remote_dtype.tcpl_id != H5P_DATATYPE_CREATE_DEFAULT &&
+ H5Pclose(dtype->remote_dtype.tcpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(dtype->tapl_id != H5P_DATATYPE_ACCESS_DEFAULT &&
+ H5Pclose(dtype->tapl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(dtype->remote_dtype.type_id != 0 &&
+ H5Tclose(dtype->remote_dtype.type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype");
+ dtype = H5FL_FREE(H5VL_iod_dtype_t, dtype);
+ break;
+ }
+
+ case HG_MAP_GET:
+ {
+ map_get_out_t *output = (map_get_out_t *)req->data;
+
+ free(output);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_SET:
+ {
+ H5VL_iod_map_set_info_t *info = (H5VL_iod_map_set_info_t *)req->data;
+
+ free(info->status);
+ info->status = NULL;
+ info->value_handle = (hg_bulk_t *)H5MM_xfree(info->value_handle);
+ info = (H5VL_iod_map_set_info_t *)H5MM_xfree(info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_MAP_DELETE:
+ case HG_LINK_CREATE:
+ case HG_LINK_MOVE:
+ case HG_LINK_REMOVE:
+ case HG_OBJECT_SET_COMMENT:
+ case HG_OBJECT_COPY:
+ {
+ int *status = (int *)req->data;
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_OBJECT_GET_COMMENT:
+ {
+ object_get_comment_out_t *result = (object_get_comment_out_t *)req->data;
+
+ free(result);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_OBJECT_OPEN_BY_TOKEN:
+ case HG_OBJECT_OPEN:
+ case HG_LINK_GET_INFO:
+ case HG_OBJECT_GET_INFO:
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ case HG_LINK_GET_VAL:
+ {
+ link_get_val_out_t *result = (link_get_val_out_t *)req->data;
+
+ free(result);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_RC_ACQUIRE:
+ {
+ H5VL_iod_rc_info_t *rc_info = (H5VL_iod_rc_info_t *)req->data;
+
+ rc_info = (H5VL_iod_rc_info_t *)H5MM_xfree(rc_info);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_RC_RELEASE:
+ case HG_RC_PERSIST:
+ case HG_RC_SNAPSHOT:
+ case HG_TR_START:
+ case HG_TR_FINISH:
+ case HG_TR_SET_DEPEND:
+ case HG_TR_SKIP:
+ case HG_TR_ABORT:
+ case HG_EVICT:
+ {
+ int *status = (int *)req->data;
+
+ free(status);
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ }
+ case HG_PREFETCH:
+ req->data = NULL;
+ H5VL_iod_request_delete(file, req);
+ break;
+ case HG_LINK_ITERATE:
+ case HG_OBJECT_VISIT:
+ case HG_MAP_ITERATE:
+ default:
+ H5VL_iod_request_delete(file, req);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Request Type not supported");
+ }
+
+ /* Free Mercury request */
+ if(HG_Request_free(*((hg_request_t *)req->req)) != HG_SUCCESS)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Can't Free Mercury Request");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_request_cancel */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_obj_requests
+ *
+ * Purpose: returns the number of requests that are associated
+ * with a particular object. If the parent array is not NULL,
+ * the request pointers are stored.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_get_obj_requests(H5VL_iod_object_t *obj, /*IN/OUT*/ size_t *count,
+ /*OUT*/ H5VL_iod_request_t **parent_reqs)
+{
+ H5VL_iod_file_t *file = obj->file;
+ H5VL_iod_request_t *cur_req = file->request_list_head;
+ size_t size = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ while(cur_req) {
+ /* If the request is pending on the object we want, add its axe_id */
+ if(cur_req->obj == obj) {
+ if(cur_req->status == H5ES_STATUS_IN_PROGRESS) {
+ if(NULL != parent_reqs) {
+ parent_reqs[size] = cur_req;
+ cur_req->ref_count ++;
+ }
+ size ++;
+ }
+ }
+ cur_req = cur_req->file_next;
+ }
+
+ *count = size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_get_obj_requests */
+
+herr_t
+H5VL_iod_get_loc_info(H5VL_iod_object_t *obj, iod_obj_id_t *iod_id,
+ iod_handles_t *iod_oh, iod_obj_id_t *mdkv_id,
+ iod_obj_id_t *attrkv_id)
+{
+ iod_obj_id_t id, md, at;
+ iod_handles_t oh;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch(obj->obj_type) {
+ case H5I_FILE:
+ oh = obj->file->remote_file.root_oh;
+ id = obj->file->remote_file.root_id;
+ md = obj->file->remote_file.mdkv_id;
+ at = obj->file->remote_file.attrkv_id;
+ break;
+ case H5I_GROUP:
+ oh = ((const H5VL_iod_group_t *)obj)->remote_group.iod_oh;
+ id = ((const H5VL_iod_group_t *)obj)->remote_group.iod_id;
+ md = ((const H5VL_iod_group_t *)obj)->remote_group.mdkv_id;
+ at = ((const H5VL_iod_group_t *)obj)->remote_group.attrkv_id;
+ break;
+ case H5I_DATASET:
+ oh = ((const H5VL_iod_dset_t *)obj)->remote_dset.iod_oh;
+ id = ((const H5VL_iod_dset_t *)obj)->remote_dset.iod_id;
+ md = ((const H5VL_iod_dset_t *)obj)->remote_dset.mdkv_id;
+ at = ((const H5VL_iod_dset_t *)obj)->remote_dset.attrkv_id;
+ break;
+ case H5I_DATATYPE:
+ oh = ((const H5VL_iod_dtype_t *)obj)->remote_dtype.iod_oh;
+ id = ((const H5VL_iod_dtype_t *)obj)->remote_dtype.iod_id;
+ md = ((const H5VL_iod_dtype_t *)obj)->remote_dtype.mdkv_id;
+ at = ((const H5VL_iod_dtype_t *)obj)->remote_dtype.attrkv_id;
+ break;
+ case H5I_MAP:
+ oh = ((const H5VL_iod_map_t *)obj)->remote_map.iod_oh;
+ id = ((const H5VL_iod_map_t *)obj)->remote_map.iod_id;
+ md = ((const H5VL_iod_map_t *)obj)->remote_map.mdkv_id;
+ at = ((const H5VL_iod_map_t *)obj)->remote_map.attrkv_id;
+ break;
+ case H5I_UNINIT:
+ case H5I_BADID:
+ case H5I_DATASPACE:
+ case H5I_ATTR:
+ case H5I_REFERENCE:
+ case H5I_VFL:
+ case H5I_VOL:
+ case H5I_ES:
+ case H5I_RC:
+ case H5I_TR:
+ case H5I_QUERY:
+ case H5I_VIEW:
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ case H5I_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "bad location object");
+ }
+
+ if(iod_id)
+ *iod_id = id;
+ if(iod_oh)
+ *iod_oh = oh;
+ if(mdkv_id)
+ *mdkv_id = md;
+ if(attrkv_id)
+ *attrkv_id = at;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_get_loc_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_parent_requests
+ *
+ * Purpose: Returns the parent requests associated with an object
+ * and transaction.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_get_parent_requests(H5VL_iod_object_t *obj, H5VL_iod_req_info_t *req_info,
+ H5VL_iod_request_t **parent_reqs, size_t *num_parents)
+{
+ size_t count = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(obj && obj->request && obj->request->status == H5ES_STATUS_IN_PROGRESS) {
+ parent_reqs[count] = obj->request;
+ obj->request->ref_count ++;
+ count ++;
+ }
+
+ if(req_info &&
+ req_info->request &&
+ req_info->request->status == H5ES_STATUS_IN_PROGRESS) {
+ parent_reqs[count] = req_info->request;
+ req_info->request->ref_count ++;
+ count ++;
+ }
+
+ *num_parents += count;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5VL_iod_get_parent_requests */
+
+herr_t
+H5VL_iod_gen_obj_id(int myrank, int nranks, uint64_t cur_index,
+ iod_obj_type_t type, uint64_t *id)
+{
+ herr_t ret_value = SUCCEED;
+ uint64_t tmp_id;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* determine first the rank of the object with the first 60 bits
+ (IOD owns 60,61,62,63). */
+ tmp_id = (uint32_t)myrank + ((uint32_t)nranks * cur_index);
+
+ /* toggle the object type bits */
+ switch(type) {
+ case IOD_OBJ_ARRAY:
+ IOD_OBJID_SETTYPE(tmp_id, IOD_OBJ_ARRAY)
+ break;
+ case IOD_OBJ_KV:
+ IOD_OBJID_SETTYPE(tmp_id, IOD_OBJ_KV)
+ break;
+ case IOD_OBJ_BLOB:
+ /* This is for HDF5 committed datatypes and not for VLEN BLOBs */
+ tmp_id &= ~(((uint64_t)0x1) << 59);
+ IOD_OBJID_SETTYPE(tmp_id, IOD_OBJ_BLOB)
+ break;
+ case IOD_OBJ_ANY:
+ case IOD_OBJ_INVALID:
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "bad object type");
+ }
+
+ /* toggle the owner bit */
+ IOD_OBJID_SETOWNER_APP(tmp_id)
+
+ *id = tmp_id;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_gen_obj_id */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_pre_write
+ *
+ * Depending on the type, this routine generates all the necessary
+ * parameters for forwarding a write call to IOD. It sets up the
+ * Mercury Bulk handle and checksums the data.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_pre_write(hid_t type_id, H5S_t *space, const void *buf,
+ /*out*/uint64_t *_checksum,
+ /*out*/uint64_t *_vlen_checksum,
+ /*out*/hg_bulk_t *bulk_handle,
+ /*out*/hg_bulk_t *vl_len_bulk_handle,
+ /*out*/hg_bulk_segment_t **_vl_segments,
+ /*out*/char **_vl_lengths)
+{
+ hsize_t buf_size = 0;
+ uint64_t checksum = 0;
+ size_t nelmts;
+ H5VL_iod_type_info_t type_info;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get type info */
+ if(H5VL_iod_get_type_info(type_id, &type_info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to get datatype info");
+
+ nelmts = (size_t)H5S_GET_SELECT_NPOINTS(space);
+
+ if(type_info.vls) {
+ hg_bulk_segment_t *segments = NULL;
+ size_t num_segments = 0;
+ char *vl_lengths = NULL;
+ size_t vl_lengths_size = 0;
+
+ HDassert(_vl_segments);
+ HDassert(_vl_lengths);
+
+ /* Create segments and vl lengths */
+ if(H5VL_iod_create_segments_send((char *)buf, &type_info, nelmts, &segments, &num_segments,
+ &vl_lengths, &vl_lengths_size, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create segments for bulk data transfer");
+ HDassert(segments);
+ HDassert(vl_lengths);
+
+ /* Register vl lengths */
+ if(HG_SUCCESS != HG_Bulk_handle_create(vl_lengths, vl_lengths_size,
+ HG_BULK_READ_ONLY, vl_len_bulk_handle))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Bulk Data Handle for vlen lengths");
+
+ /* Register non-contiguous memory segments */
+ if(HG_SUCCESS != HG_Bulk_handle_create_segments(segments, num_segments,
+ HG_BULK_READ_ONLY, bulk_handle))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Bulk Data handle");
+
+ if(_checksum)
+ checksum = H5_checksum_crc64_segments(segments, num_segments);
+ if(_vlen_checksum)
+ *_vlen_checksum = H5_checksum_crc64(vl_lengths, vl_lengths_size);
+
+ *_vl_segments = segments;
+ *_vl_lengths = vl_lengths;
+ }
+ else {
+ H5T_t *dt = NULL;
+ size_t type_size;
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
+
+ *vl_len_bulk_handle = HG_BULK_NULL;
+ type_size = H5T_get_size(dt);
+
+ buf_size = type_size * nelmts;
+
+ if(_checksum) {
+ checksum = H5S_checksum(buf, type_size, nelmts, space);
+ }
+
+ /* If the memory selection is contiguous, create simple HG Bulk Handle */
+ if(H5S_select_is_contiguous(space)) {
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(buf, (size_t)buf_size,
+ HG_BULK_READ_ONLY, bulk_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+ }
+
+ /* if the memory selection is non-contiguous, create a segmented selection */
+ else {
+ hsize_t *off = NULL; /* array that contains the memory addresses of the memory selection */
+ size_t *len = NULL; /* array that contains the length of a contiguous block at each address */
+ size_t count = 0; /* number of offset/length entries in selection */
+ size_t i;
+ hg_bulk_segment_t *bulk_segments = NULL;
+ uint8_t *start_offset = (uint8_t *) buf;
+
+ /* generate the offsets/lengths pair arrays from the memory dataspace selection */
+ if(H5S_get_offsets(space, type_size, nelmts, &off, &len, &count) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't retrieve offets/lengths of memory space");
+
+ /* Register memory with segmented HG handle */
+ bulk_segments = (hg_bulk_segment_t *)malloc(count * sizeof(hg_bulk_segment_t));
+ for (i = 0; i < count ; i++) {
+ bulk_segments[i].address = (void *)(start_offset + off[i]);
+ bulk_segments[i].size = len[i];
+ }
+
+ /* create Bulk handle */
+ if (HG_SUCCESS != HG_Bulk_handle_create_segments(bulk_segments, count,
+ HG_BULK_READ_ONLY, bulk_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+
+ /* cleanup */
+ if(count) {
+ free(bulk_segments);
+ bulk_segments = NULL;
+ free(len);
+ len = NULL;
+ free(off);
+ off = NULL;
+ }
+ }
+ }
+
+ if(_checksum) {
+ *_checksum = checksum;
+ }
+
+ H5VL_iod_type_info_reset(&type_info);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_pre_write */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_pre_read
+ *
+ * Depending on the type, this routine generates all the necessary
+ * parameters for forwarding a write call to IOD. It sets up the
+ * Mercury Bulk handle and checksums the data.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_pre_read(hid_t type_id, H5S_t *space, const void *buf, hssize_t nelmts,
+ /*out*/hg_bulk_t *bulk_handle)
+{
+ size_t buf_size = 0;
+ H5T_t *dt = NULL;
+ size_t type_size;
+ 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")
+
+ type_size = H5T_get_size(dt);
+ buf_size = type_size * (size_t)nelmts;
+
+ /* If the memory selection is contiguous, create simple HG Bulk Handle */
+ if(H5S_select_is_contiguous(space)) {
+ /* Register memory with bulk_handle */
+ if(HG_SUCCESS != HG_Bulk_handle_create(buf, buf_size,
+ HG_BULK_READWRITE, bulk_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+ }
+
+ /* if the memory selection is non-contiguous, create a segmented selection */
+ else {
+ hsize_t *off = NULL; /* array that contains the memory addresses of the memory selection */
+ size_t *len = NULL; /* array that contains the length of a contiguous block at each address */
+ size_t count = 0; /* number of offset/length entries in selection */
+ size_t i;
+ hg_bulk_segment_t *bulk_segments = NULL;
+ uint8_t *start_offset = (uint8_t *) buf;
+
+ /* generate the offsets/lengths pair arrays from the memory dataspace selection */
+ if(H5S_get_offsets(space, type_size, (size_t)nelmts, &off, &len, &count) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't retrieve offets/lengths of memory space");
+
+ /* Register memory with segmented HG handle */
+ bulk_segments = (hg_bulk_segment_t *)malloc(count * sizeof(hg_bulk_segment_t));
+ for (i = 0; i < count ; i++) {
+ bulk_segments[i].address = (void *)(start_offset + off[i]);
+ bulk_segments[i].size = len[i];
+ }
+
+ /* create Bulk handle */
+ if (HG_SUCCESS != HG_Bulk_handle_create_segments(bulk_segments, count,
+ HG_BULK_READWRITE, bulk_handle))
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't create Bulk Data Handle");
+
+ /* cleanup */
+ if(count) {
+ free(bulk_segments);
+ bulk_segments = NULL;
+ free(len);
+ len = NULL;
+ free(off);
+ off = NULL;
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_pre_read */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_vl_map_get_finalize
+ *
+ * Finalize the data read by deserializing it into the user's buffer.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_vl_map_get_finalize(size_t buf_size, void *read_buf,
+ void *user_buf, hid_t mem_type_id)
+{
+ H5T_t *mem_dt = NULL;
+ H5T_t *super = NULL;
+ size_t super_size;
+ H5T_class_t dt_class;
+ uint8_t *buf_ptr = (uint8_t *)read_buf;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (mem_dt = (H5T_t *)H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
+ if(NULL == (super = H5T_get_super(mem_dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid super type of VL type");
+
+ super_size = H5T_get_size(super);
+ dt_class = H5T_get_class(mem_dt, FALSE);
+
+#if 0
+ {
+ size_t seq_len = buf_size, u;
+
+ if(H5T_STRING == dt_class)
+ fprintf(stderr, "String Length %zu: %s\n", buf_size, (char *)read_buf);
+ else if(H5T_VLEN == dt_class) {
+ int *ptr = (int *)buf_ptr;
+ fprintf(stderr, "Sequence Count %zu: ", buf_size/sizeof(int));
+ for(u=0 ; u<buf_size/sizeof(int) ; ++u)
+ fprintf(stderr, "%d ", ptr[u]);
+ fprintf(stderr, "\n");
+ }
+ }
+#endif
+
+ if(H5T_VLEN == dt_class) {
+ hvl_t *vl = (hvl_t *)user_buf;
+
+ vl->len = buf_size/super_size;
+ vl->p = malloc(buf_size);
+ HDmemcpy(vl->p, buf_ptr, buf_size);
+ buf_ptr += buf_size;
+ }
+ else if(H5T_STRING == dt_class) {
+ char **buf = (char **)user_buf;
+
+ //elmt_size = *((size_t *)buf_ptr);
+ //buf_ptr += sizeof(size_t);
+
+ *buf = HDstrdup((char *)buf_ptr);
+ //buf_ptr += elmt_size;
+ }
+
+done:
+ if(super && H5T_close(super) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't close super type")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_vl_map_get_finalize */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_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
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_map_get_size(hid_t type_id, const void *buf,
+ /*out*/uint64_t *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;
+
+ /* compute checksum */
+ *checksum = H5_checksum_crc64(buf, buf_size);
+ 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);
+
+ /* compute checksum */
+ *checksum = H5_checksum_crc64(buf, buf_size);
+ 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;
+
+ /* compute checksum */
+ *checksum = H5_checksum_crc64(vl->p, buf_size);
+ H5T_close(super);
+ break;
+ }
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "unsupported datatype");
+ }
+ *size = buf_size;
+ if(ret_class)
+ *ret_class = dt_class;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_get_size */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_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
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_map_dtype_info(hid_t type_id, /*out*/ hbool_t *is_vl, /*out*/size_t *size)
+{
+ 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;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_map_get_size */
+
+#if 0
+static herr_t
+H5VL_generate_axe_ids(int myrank, int nranks, uint64_t *start_id)
+{
+ uint64_t seed;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ seed = (pow(2,64) - 1) / nranks;
+ *start_id = seed * my_rank;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+H5VL_iod_get_axe_id(int myrank, int nranks, int cur_index, uint64_t *id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_parent_info
+ *
+ * Purpose: This routine traverses the path in name, or in loc_params
+ * if the path is specified there, to determine the components
+ * of the path that are present locally in the ID space.
+ * Once a component in the path is not found, the routine
+ * breaks at that point and stores the remaining path in new_name.
+ * This is where the traversal can begin at the server.
+ * The IOD ID, OH, and axe_id belonging to the last object
+ * present are returned too.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_get_parent_info(H5VL_iod_object_t *obj, H5VL_loc_params_t loc_params,
+ const char *name, /*OUT*/iod_obj_id_t *iod_id,
+ /*OUT*/iod_handle_t *iod_oh, /*OUT*/H5VL_iod_request_t **parent_req,
+ /*OUT*/char **new_name, /*OUT*/H5VL_iod_object_t **last_obj)
+{
+ iod_obj_id_t cur_id;
+ iod_handle_t cur_oh;
+ size_t cur_size; /* current size of the path traversed so far */
+ char *cur_name; /* full path to object that is currently being looked for */
+ H5VL_iod_object_t *cur_obj = obj; /* current object in the traversal loop */
+ H5VL_iod_object_t *next_obj = NULL; /* the next object to traverse */
+ const char *path; /* specified path for the object to traverse to */
+ H5WB_t *wb = NULL; /* Wrapped buffer for temporary buffer */
+ char comp_buf[1024]; /* Temporary buffer for path components */
+ char *comp; /* Pointer to buffer for path components */
+ size_t nchars; /* component name length */
+ H5VL_iod_file_t *file = obj->file; /* pointer to file where the search happens */
+ hbool_t last_comp = FALSE; /* Flag to indicate that a component is the last component in the name */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(loc_params.type == H5VL_OBJECT_BY_SELF)
+ path = name;
+ else if (loc_params.type == H5VL_OBJECT_BY_NAME)
+ path = loc_params.loc_data.loc_by_name.name;
+
+ if (NULL == (cur_name = (char *)malloc(HDstrlen(obj->obj_name) + HDstrlen(path) + 2)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate");
+
+ HDstrcpy(cur_name, obj->obj_name);
+ cur_size = HDstrlen(obj->obj_name);
+
+ if(obj->obj_type != H5I_FILE) {
+ HDstrcat(cur_name, "/");
+ cur_size += 1;
+ }
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(comp_buf, sizeof(comp_buf))))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+ /* Get a pointer to a buffer that's large enough */
+ if(NULL == (comp = (char *)H5WB_actual(wb, (HDstrlen(path) + 1))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Traverse the path */
+ while((path = H5G__component(path, &nchars)) && *path) {
+ const char *s; /* Temporary string pointer */
+
+ /*
+ * Copy the component name into a null-terminated buffer so
+ * we can pass it down to the other symbol table functions.
+ */
+ HDmemcpy(comp, path, nchars);
+ comp[nchars] = '\0';
+
+ /*
+ * The special name `.' is a no-op.
+ */
+ if('.' == comp[0] && !comp[1]) {
+ path += nchars;
+ continue;
+ } /* end if */
+
+ /* Check if this is the last component of the name */
+ if(!((s = H5G__component(path + nchars, NULL)) && *s))
+ last_comp = TRUE;
+
+ HDstrcat(cur_name, comp);
+ cur_size += nchars;
+ cur_name[cur_size] = '\0';
+
+ if(NULL == (next_obj = (const H5VL_iod_object_t *)H5I_search_name(file, cur_name, H5I_GROUP))) {
+ if(last_comp) {
+ if(NULL == (next_obj = (const H5VL_iod_object_t *)H5I_search_name
+ (file, cur_name, H5I_DATASET))
+ && NULL == (next_obj = (H5VL_iod_object_t *)H5I_search_name
+ (file, cur_name, H5I_DATATYPE))
+ && NULL == (next_obj = (H5VL_iod_object_t *)H5I_search_name
+ (file, cur_name, H5I_MAP)))
+ break;
+ }
+ else {
+ break;
+ }
+ }
+
+#if H5VL_IOD_DEBUG
+ printf("Found %s Locally\n", comp);
+#endif
+
+ /* Advance to next component in string */
+ path += nchars;
+ HDstrcat(cur_name, "/");
+ cur_size += 1;
+ cur_obj = next_obj;
+ }
+
+ switch(cur_obj->obj_type) {
+ case H5I_FILE:
+ cur_oh = cur_obj->file->remote_file.root_oh;
+ cur_id = cur_obj->file->remote_file.root_id;
+ break;
+ case H5I_GROUP:
+ cur_oh = ((const H5VL_iod_group_t *)cur_obj)->remote_group.iod_oh;
+ cur_id = ((const H5VL_iod_group_t *)cur_obj)->remote_group.iod_id;
+ break;
+ case H5I_DATASET:
+ cur_oh = ((const H5VL_iod_dset_t *)cur_obj)->remote_dset.iod_oh;
+ cur_id = ((const H5VL_iod_dset_t *)cur_obj)->remote_dset.iod_id;
+ break;
+ case H5I_DATATYPE:
+ cur_oh = ((const H5VL_iod_dtype_t *)cur_obj)->remote_dtype.iod_oh;
+ cur_id = ((const H5VL_iod_dtype_t *)cur_obj)->remote_dtype.iod_id;
+ break;
+ case H5I_MAP:
+ cur_oh = ((const H5VL_iod_map_t *)cur_obj)->remote_map.iod_oh;
+ cur_id = ((const H5VL_iod_map_t *)cur_obj)->remote_map.iod_id;
+ break;
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "bad location object");
+ }
+
+ if(cur_obj->request && cur_obj->request->status == H5ES_STATUS_IN_PROGRESS) {
+ *parent_req = cur_obj->request;
+ cur_obj->request->ref_count ++;
+ }
+ else {
+ *parent_req = NULL;
+ HDassert(cur_oh.cookie != IOD_OH_UNDEFINED);
+ }
+
+ *iod_id = cur_id;
+ *iod_oh = cur_oh;
+
+ if(*path)
+ *new_name = strdup(path);
+ else
+ *new_name = strdup(".");
+
+ if(last_obj)
+ *last_obj = cur_obj;
+
+done:
+ free(cur_name);
+ /* Release temporary component buffer */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't release wrapped buffer")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_get_parent_info */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_search_name
+ *
+ * Purpose: return pointer to object with given full path name
+ *
+ * Return: Success: pointer to object
+ * Failure: NULL (not found)
+ *
+ * Programmer: Mohamad Chaarawi
+ * March 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+const void *
+H5I_search_name(void *_file, char *name, H5I_type_t type)
+{
+ H5I_id_type_t *type_ptr; /*ptr to the type */
+ const void *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ type_ptr = H5I_id_type_list_g[type];
+ if(type_ptr == NULL || type_ptr->count <= 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
+
+ /* Only iterate through hash table if there are IDs in group */
+ if(type_ptr->ids > 0) {
+ H5I_id_info_t *id_ptr; /*ptr to the new ID */
+ unsigned i; /*counter */
+
+ /* Start at the beginning of the array */
+ for(i = 0; i < type_ptr->cls->hash_size; i++) {
+ id_ptr = type_ptr->id_list[i];
+ while(id_ptr) {
+ H5VL_iod_file_t *file = (H5VL_iod_file_t *)_file;
+
+ switch(type) {
+ case H5I_GROUP:
+ {
+ const H5VL_iod_group_t *grp = (const H5VL_iod_group_t *)id_ptr->obj_ptr;
+
+ if (file == grp->common.file &&
+ 0 == strcmp(grp->common.obj_name, name)) {
+ ret_value = id_ptr->obj_ptr;
+ HGOTO_DONE(id_ptr->obj_ptr);
+ }
+ break;
+ }
+ case H5I_DATASET:
+ {
+ const H5VL_iod_dset_t *dset = (const H5VL_iod_dset_t *)id_ptr->obj_ptr;
+
+ if (file == dset->common.file &&
+ 0 == strcmp(dset->common.obj_name, name)) {
+ ret_value = id_ptr->obj_ptr;
+ HGOTO_DONE(id_ptr->obj_ptr);
+ }
+ break;
+ }
+ case H5I_MAP:
+ {
+ const H5VL_iod_map_t *map = (const H5VL_iod_map_t *)id_ptr->obj_ptr;
+
+ if (file == map->common.file &&
+ 0 == strcmp(map->common.obj_name, name)) {
+ ret_value = id_ptr->obj_ptr;
+ HGOTO_DONE(id_ptr->obj_ptr);
+ }
+ break;
+ }
+ case H5I_DATATYPE:
+ {
+ const H5T_t *dt = (const H5T_t *)id_ptr->obj_ptr;
+
+ if(H5T_committed(dt)) {
+ const H5VL_iod_dtype_t *dtype ;
+
+ dtype = (const H5VL_iod_dtype_t *)H5T_get_named_type(dt);
+
+ if (file == dtype->common.file &&
+ 0 == strcmp(dtype->common.obj_name, name)) {
+ ret_value = id_ptr->obj_ptr;
+ HGOTO_DONE(id_ptr->obj_ptr);
+ }
+ }
+ break;
+ }
+ default:
+ HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type")
+ }
+ id_ptr = id_ptr->next;
+ } /* end while */
+ } /* end for */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_search_name() */
+
+#endif
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_client.h b/src/H5VLiod_client.h
new file mode 100644
index 0000000..4de6041
--- /dev/null
+++ b/src/H5VLiod_client.h
@@ -0,0 +1,450 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5VL iod client module
+ */
+#ifndef _H5VLiod_client_H
+#define _H5VLiod_client_H
+
+#include "H5FFprivate.h" /* FastForward wrappers */
+#include "H5Mpublic.h"
+#include "H5Sprivate.h"
+#include "H5RCprivate.h" /* Read contexts */
+#include "H5TRprivate.h" /* Transactions */
+#include "H5VLiod_common.h"
+
+#ifdef H5_HAVE_EFF
+
+/* forward declaration of file struct */
+struct H5VL_iod_file_t;
+/* forward declaration of object struct */
+struct H5VL_iod_object_t;
+
+/* enum for types of requests */
+typedef enum H5RQ_type_t {
+ HG_ANALYSIS_EXECUTE,
+ HG_FILE_CREATE,
+ HG_FILE_OPEN,
+ HG_FILE_CLOSE,
+ HG_ATTR_CREATE,
+ HG_ATTR_OPEN,
+ HG_ATTR_READ,
+ HG_ATTR_WRITE,
+ HG_ATTR_EXISTS,
+ HG_ATTR_RENAME,
+ HG_ATTR_REMOVE,
+ HG_ATTR_CLOSE,
+ HG_GROUP_CREATE,
+ HG_GROUP_OPEN,
+ HG_GROUP_CLOSE,
+ HG_DSET_CREATE,
+ HG_DSET_OPEN,
+ HG_DSET_READ,
+ HG_DSET_WRITE,
+ HG_DSET_GET_VL_SIZE,
+ HG_DSET_SET_EXTENT,
+ HG_DSET_CLOSE,
+ HG_DTYPE_COMMIT,
+ HG_DTYPE_OPEN,
+ HG_DTYPE_CLOSE,
+ HG_LINK_CREATE,
+ HG_LINK_MOVE,
+ HG_LINK_ITERATE,
+ HG_LINK_EXISTS,
+ HG_LINK_GET_INFO,
+ HG_LINK_GET_VAL,
+ HG_LINK_REMOVE,
+ HG_MAP_CREATE,
+ HG_MAP_OPEN,
+ HG_MAP_SET,
+ HG_MAP_GET,
+ HG_MAP_GET_COUNT,
+ HG_MAP_EXISTS,
+ HG_MAP_ITERATE,
+ HG_MAP_DELETE,
+ HG_MAP_CLOSE,
+ HG_OBJECT_OPEN_BY_TOKEN,
+ HG_OBJECT_OPEN,
+ HG_OBJECT_COPY,
+ HG_OBJECT_VISIT,
+ HG_OBJECT_EXISTS,
+ HG_OBJECT_SET_COMMENT,
+ HG_OBJECT_GET_COMMENT,
+ HG_OBJECT_GET_INFO,
+ HG_RC_ACQUIRE,
+ HG_RC_RELEASE,
+ HG_RC_PERSIST,
+ HG_RC_SNAPSHOT,
+ HG_TR_START,
+ HG_TR_FINISH,
+ HG_TR_SET_DEPEND,
+ HG_TR_SKIP,
+ HG_TR_ABORT,
+ HG_PREFETCH,
+ HG_EVICT
+} H5RQ_type_t;
+
+/* the client IOD VOL request struct */
+typedef struct H5VL_iod_request_t {
+ H5RQ_type_t type; /* The operation type of this request */
+ void *data; /* data associated with request (usually used at completion time) */
+ void *req; /* the request pointer correponding to the Mercury request */
+ struct H5VL_iod_object_t *obj; /* The object pointer that this request is associated with */
+ H5VL_iod_state_t state; /* current internal state of the request */
+ H5ES_status_t status; /* external status given to use of request */
+ uint64_t axe_id; /* The AXE ID this request was assigned */
+ unsigned ref_count; /* reference count to know when this request can be freed. */
+ H5VL_iod_req_info_t *trans_info; /* pointer to transaction or read context struct for this request */
+
+ size_t num_parents; /* Number of parents this request has (in AXE) */
+ struct H5VL_iod_request_t **parent_reqs; /* an array of the parent request pointers */
+
+ /* Linked list pointers for the container this request was generated. */
+ struct H5VL_iod_request_t *file_prev;
+ struct H5VL_iod_request_t *file_next;
+
+ /* Linked list pointers for all IOD VOL requests in the library */
+ struct H5VL_iod_request_t *global_prev;
+ struct H5VL_iod_request_t *global_next;
+
+ /* Linked list pointers for the transaction this request belong to */
+ struct H5VL_iod_request_t *trans_prev;
+ struct H5VL_iod_request_t *trans_next;
+} H5VL_iod_request_t;
+
+/* struct that contains the information about the IOD container */
+typedef struct H5VL_iod_remote_file_t {
+ /* Do NOT change the order of the parameters */
+ iod_handle_t coh;
+ iod_handles_t root_oh;
+ uint64_t kv_oid_index;
+ uint64_t array_oid_index;
+ uint64_t blob_oid_index;
+ iod_obj_id_t root_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ iod_obj_id_t oidkv_id;
+ uint64_t c_version;
+ hid_t fcpl_id;
+} H5VL_iod_remote_file_t;
+
+/* struct that contains the information about the IOD attr */
+typedef struct H5VL_iod_remote_attr_t {
+ /* Do NOT change the order of the parameters */
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ hid_t type_id;
+ hid_t space_id;
+} H5VL_iod_remote_attr_t;
+
+/* struct that contains the information about the IOD group */
+typedef struct H5VL_iod_remote_group_t {
+ /* Do NOT change the order of the parameters */
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ hid_t gcpl_id;
+} H5VL_iod_remote_group_t;
+
+/* struct that contains the information about the IOD map */
+typedef struct H5VL_iod_remote_map_t {
+ /* Do NOT change the order of the parameters */
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ hid_t keytype_id;
+ hid_t valtype_id;
+ hid_t mcpl_id;
+} H5VL_iod_remote_map_t;
+
+/* struct that contains the information about the IOD dset */
+typedef struct H5VL_iod_remote_dset_t {
+ /* Do NOT change the order of the parameters */
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ hid_t dcpl_id;
+ hid_t type_id;
+ hid_t space_id;
+} H5VL_iod_remote_dset_t;
+
+/* struct that contains the information about the IOD dtype */
+typedef struct H5VL_iod_remote_dtype_t {
+ /* Do NOT change the order of the parameters */
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ hid_t tcpl_id;
+ hid_t type_id;
+} H5VL_iod_remote_dtype_t;
+
+/* struct that contains the information about a generic IOD object */
+typedef struct H5VL_iod_remote_object_t {
+ /* Do NOT change the order of the parameters */
+ H5I_type_t obj_type;
+ iod_handles_t iod_oh;
+ iod_obj_id_t iod_id;
+ iod_obj_id_t mdkv_id;
+ iod_obj_id_t attrkv_id;
+ hid_t cpl_id;
+ hid_t id1;
+ hid_t id2;
+} H5VL_iod_remote_object_t;
+
+/* a common strcut between all client side objects */
+typedef struct H5VL_iod_object_t {
+ H5I_type_t obj_type;
+ char *obj_name;
+ char *comment;
+ H5VL_iod_request_t *request;
+ struct H5VL_iod_file_t *file;
+} H5VL_iod_object_t;
+
+/* the client side file struct */
+typedef struct H5VL_iod_file_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_file_t remote_file;
+ char *file_name;
+ unsigned flags;
+ uint32_t md_integrity_scope;
+ hid_t fapl_id;
+ MPI_Comm comm;
+ MPI_Info info;
+ int my_rank;
+ int num_procs;
+ size_t num_req;
+ unsigned nopen_objs;
+ H5VL_iod_request_t *request_list_head;
+ H5VL_iod_request_t *request_list_tail;
+} H5VL_iod_file_t;
+
+/* the client side attribute struct */
+typedef struct H5VL_iod_attr_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_attr_t remote_attr;
+ char *loc_name;
+} H5VL_iod_attr_t;
+
+/* the client side group struct */
+typedef struct H5VL_iod_group_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_group_t remote_group;
+ hid_t gapl_id;
+} H5VL_iod_group_t;
+
+/* the client side map struct */
+typedef struct H5VL_iod_map_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_map_t remote_map;
+ hid_t mapl_id;
+} H5VL_iod_map_t;
+
+/* the client side dataset struct */
+typedef struct H5VL_iod_dset_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_dset_t remote_dset;
+ hid_t dapl_id;
+} H5VL_iod_dset_t;
+
+/* the client side datatype struct */
+typedef struct H5VL_iod_dtype_t {
+ H5VL_iod_object_t common; /* must be first */
+ H5VL_iod_remote_dtype_t remote_dtype;
+ hid_t tapl_id;
+} H5VL_iod_dtype_t;
+
+/* information about an attr IO request */
+typedef struct H5VL_iod_attr_io_info_t {
+ int *status;
+ hg_bulk_t *bulk_handle;
+} H5VL_iod_attr_io_info_t;
+
+/* information about a dataset write request */
+typedef struct H5VL_iod_write_info_t {
+ void *status;
+ hg_bulk_t *bulk_handle;
+ hg_bulk_t *vl_len_bulk_handle;
+ hg_bulk_segment_t *vl_segments;
+ char *vl_lengths;
+} H5VL_iod_write_info_t;
+
+/* status of a read operation after it completes */
+typedef struct H5VL_iod_read_status_t {
+ int ret;
+ uint64_t cs;
+ size_t buf_size;
+} H5VL_iod_read_status_t;
+
+/* information about a dataset read request */
+typedef struct H5VL_iod_read_info_t {
+ void *status;
+ hg_bulk_t *bulk_handle;
+ void *buf_ptr;
+ char *vl_lengths;
+ size_t vl_lengths_size;
+ H5VL_iod_type_info_t *type_info;
+ hssize_t nelmts;
+ size_t type_size;
+ struct H5S_t *space;
+ uint64_t *cs_ptr;
+ uint32_t raw_cs_scope;
+ hid_t file_space_id;
+ hid_t mem_type_id;
+ hid_t dxpl_id;
+ uint64_t axe_id;
+ na_addr_t ion_target;
+ hg_id_t read_id;
+} H5VL_iod_read_info_t;
+
+typedef struct H5VL_iod_map_set_info_t {
+ void *status;
+ hg_bulk_t *value_handle;
+} H5VL_iod_map_set_info_t;
+
+/* information about a map get request */
+typedef struct H5VL_iod_map_io_info_t {
+ /* read & write params */
+ map_get_out_t *output; /* this must be first */
+ void *val_ptr;
+ void *read_buf;
+ hg_bulk_t *value_handle;
+ size_t val_size;
+ uint32_t raw_cs_scope;
+ uint64_t *val_cs_ptr;
+ hid_t val_mem_type_id;
+ hid_t key_mem_type_id;
+ hid_t dxpl_id;
+ hbool_t val_is_vl;
+ hid_t rcxt_id;
+ binary_buf_t key;
+ na_addr_t peer;
+ hg_id_t map_get_id;
+} H5VL_iod_map_io_info_t;
+
+/* information about a read context acquire request*/
+typedef struct H5VL_iod_rc_info_t {
+ rc_acquire_out_t result;
+ H5RC_t *read_cxt;
+ uint64_t *c_version_ptr;
+} H5VL_iod_rc_info_t;
+
+/* information about a transaction start request*/
+typedef struct H5VL_iod_tr_info_t {
+ int result;
+ H5TR_t *tr;
+} H5VL_iod_tr_info_t;
+
+/* information about an exists request*/
+typedef struct H5VL_iod_exists_info_t {
+ hbool_t *user_bool; /* pointer to the user provided hbool_t */
+ htri_t server_ret; /* the return value from the server */
+} H5VL_iod_exists_info_t;
+
+H5_DLL herr_t H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request);
+H5_DLL herr_t H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request);
+H5_DLL herr_t H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request);
+H5_DLL herr_t H5VL_iod_request_wait_all(H5VL_iod_file_t *file);
+H5_DLL herr_t H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object);
+H5_DLL herr_t H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req);
+H5_DLL herr_t H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req);
+H5_DLL herr_t H5VL_iod_request_decr_rc(H5VL_iod_request_t *request);
+
+H5_DLL herr_t H5VL_iod_get_parent_requests(H5VL_iod_object_t *obj, H5VL_iod_req_info_t *req_info,
+ H5VL_iod_request_t **parent_reqs, size_t *num_parents);
+H5_DLL herr_t H5VL_iod_get_loc_info(H5VL_iod_object_t *obj, iod_obj_id_t *iod_id,
+ iod_handles_t *iod_oh, iod_obj_id_t *mdkv_oh,
+ iod_obj_id_t *attrkv_oh);
+H5_DLL herr_t H5VL_iod_get_obj_requests(H5VL_iod_object_t *obj, /*IN/OUT*/ size_t *count,
+ /*OUT*/ H5VL_iod_request_t **parent_reqs);
+H5_DLL herr_t H5VL__iod_create_and_forward(hg_id_t op_id, H5RQ_type_t op_type,
+ H5VL_iod_object_t *request_obj, htri_t track,
+ size_t num_parents, H5VL_iod_request_t **parent_reqs,
+ H5VL_iod_req_info_t *req_info,
+ void *input, void *output, void *data, void **req);
+
+H5_DLL herr_t H5VL_iod_map_dtype_info(hid_t type_id, /*out*/ hbool_t *is_vl, /*out*/size_t *size);
+H5_DLL herr_t H5VL_iod_map_get_size(hid_t type_id, const void *buf,
+ /*out*/uint64_t *checksum,
+ /*out*/size_t *size, /*out*/H5T_class_t *dt_class);
+H5_DLL herr_t H5VL_iod_gen_obj_id(int myrank, int nranks, uint64_t cur_index,
+ iod_obj_type_t type, uint64_t *id);
+H5_DLL herr_t H5VL_iod_pre_write(hid_t type_id, H5S_t *space, const void *buf,
+ /*out*/uint64_t *_checksum,
+ /*out*/uint64_t *_vlen_checksum,
+ /*out*/hg_bulk_t *bulk_handle,
+ /*out*/hg_bulk_t *vl_len_bulk_handle,
+ /*out*/hg_bulk_segment_t **_vl_segments,
+ /*out*/char **_vl_lengths);
+H5_DLL herr_t H5VL_iod_pre_read(hid_t type_id, struct H5S_t *space, const void *buf,
+ hssize_t nelmts, /*out*/hg_bulk_t *bulk_handle);
+
+/* private routines for map objects */
+H5_DLL herr_t H5M_init(void);
+H5_DLL void *H5VL_iod_map_create(void *obj, H5VL_loc_params_t loc_params, const char *name,
+ hid_t keytype, hid_t valtype, hid_t lcpl_id, hid_t mcpl_id,
+ hid_t mapl_id, hid_t trans_id, void **req);
+H5_DLL void *H5VL_iod_map_open(void *obj, H5VL_loc_params_t loc_params,
+ const char *name, hid_t mapl_id, hid_t rcxt_id, void **req);
+H5_DLL herr_t H5VL_iod_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,
+ hid_t trans_id, void **req);
+H5_DLL herr_t H5VL_iod_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,
+ hid_t rcxt_id, void **req);
+H5_DLL herr_t H5VL_iod_map_get_types(void *map, hid_t *key_type_id, hid_t *val_type_id,
+ hid_t rcxt_id, void **req);
+H5_DLL herr_t H5VL_iod_map_get_count(void *map, hsize_t *count, hid_t rcxt_id, void **req);
+H5_DLL herr_t H5VL_iod_map_exists(void *map, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, hid_t rcxt_id, void **req);
+H5_DLL herr_t H5VL_iod_map_iterate(void *map, hid_t key_mem_type_id, hid_t value_mem_type_id,
+ H5M_iterate_func_t callback_func, void *context);
+H5_DLL herr_t H5VL_iod_map_delete(void *map, hid_t key_mem_type_id, const void *key,
+ hid_t trans_id, void **req);
+H5_DLL herr_t H5VL_iod_map_close(void *map, void **req);
+
+H5_DLL void * H5VL_iod_obj_open_token(const void *token, H5TR_t *tr,
+ H5I_type_t *opened_type, void **req);
+
+/* private routines for RC */
+H5_DLL herr_t H5VL_iod_rc_acquire(H5VL_iod_file_t *file, H5RC_t *rc,
+ uint64_t *c_version, hid_t rcapl_id, void **req);
+H5_DLL herr_t H5VL_iod_rc_release(H5RC_t *rc, void **req);
+H5_DLL herr_t H5VL_iod_rc_persist(H5RC_t *rc, void **req);
+H5_DLL herr_t H5VL_iod_rc_snapshot(H5RC_t *rc, const char *snapshot_name, void **req);
+
+/* private routines for TR */
+H5_DLL herr_t H5VL_iod_tr_start(H5TR_t *tr, hid_t trspl_id, void **req);
+H5_DLL herr_t H5VL_iod_tr_finish(H5TR_t *tr, hbool_t acquire, hid_t trfpl_id, void **req);
+H5_DLL herr_t H5VL_iod_tr_set_dependency(H5TR_t *tr, uint64_t trans_num, void **req);
+H5_DLL herr_t H5VL_iod_tr_skip(H5VL_iod_file_t *file, uint64_t start_trans_num,
+ uint64_t count, void **req);
+H5_DLL herr_t H5VL_iod_tr_abort(H5TR_t *tr, void **req);
+
+H5_DLL herr_t H5VL_iod_prefetch(void *obj, hid_t rcxt_id, hrpl_t *replica_id,
+ hid_t apl_id, void **req);
+H5_DLL herr_t H5VL_iod_evict(void *obj, uint64_t c_version, hid_t apl_id, void **req);
+
+H5_DLL herr_t H5VL_iod_analysis_execute(const char *file_name, const char *obj_name,
+ hid_t query_id, const char *split_script, const char *combine_script,
+ void **req);
+
+#endif /* H5_HAVE_EFF */
+#endif /* _H5VLiod_client_H */
diff --git a/src/H5VLiod_common.c b/src/H5VLiod_common.c
new file mode 100644
index 0000000..9047613
--- /dev/null
+++ b/src/H5VLiod_common.c
@@ -0,0 +1,1020 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of h5netvol. The full h5netvol copyright notice, *
+ * including terms governing use, modification, and redistribution, is *
+ * contained in the file COPYING at the root of the source code distribution *
+ * tree. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include "H5VLiod_common.h"
+#ifdef H5_HAVE_EFF
+#include <mchecksum.h> /* Mercury Checksum library */
+#endif /* H5_HAVE_EFF */
+
+/*
+ * Local typedefs
+ */
+/* Structure for a compound member type */
+typedef struct H5VL_iod_cmpd_info_t {
+ size_t offset;
+ hid_t type_id;
+} H5VL_iod_cmpd_info_t;
+
+/* Macros for error handling */
+#define SUCCEED 0
+#define FAIL -1
+#define PRINT_ERROR(MSG) \
+do { \
+ fprintf(stderr, "ERROR at %s:%d in %s()...\n%s\n", __FILE__, __LINE__, __FUNCTION__,MSG); \
+} while(0)
+#define ERROR(MSG) \
+do { \
+ PRINT_ERROR(MSG); \
+ goto error; \
+} while(0)
+
+#define TRUE 1
+#define FALSE 0
+
+/* Macros to encode and decode a uint64_t */
+# define UINT64ENCODE(p, n) \
+ do { \
+ uint64_t _n = (n); \
+ size_t _i; \
+ uint8_t *_p = (uint8_t*)(p); \
+\
+ for (_i = 0; _i < sizeof(uint64_t); _i++, _n >>= 8) \
+ *_p++ = (uint8_t)(_n & 0xff); \
+ for (/*void*/; _i < 8; _i++) \
+ *_p++ = 0; \
+ } while(0)
+
+# define UINT64DECODE(p, n) \
+ do { \
+ /* WE DON'T CHECK FOR OVERFLOW! */ \
+ size_t _i; \
+ uint8_t *_p = (uint8_t*)(p); \
+\
+ n = 0; \
+ (_p) += 8; \
+ for (_i = 0; _i < sizeof(uint64_t); _i++) \
+ n = (n << 8) | *(--_p); \
+ } while(0)
+
+/*
+ * Local functions
+ */
+static int H5VL_iod_cmpd_qsort_cb(const void *_memb1, const void *_memb2);
+static int H5VL_iod_get_type_info_helper(hid_t type_id,
+ H5VL_iod_type_info_t *type_info, size_t offset, size_t *vls_nalloc);
+static int H5VL_iod_cs_send_helper(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ size_t *segments_nalloc, char **vl_lengths, size_t *vl_lengths_nused,
+ size_t *vl_lengths_nalloc, void ***free_list, size_t *free_list_len,
+ size_t *free_list_nalloc);
+static int H5VL_iod_cs_recv_helper(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ size_t *segments_nalloc, char *vl_lengths, size_t *vl_lengths_loc,
+ size_t vl_lengths_nused, void ***free_list, size_t *free_list_len,
+ size_t *free_list_nalloc);
+
+
+/*
+ * Local macros
+ */
+#define H5VL_IOD_ARR_ADD(TYPE, ARR, NUSED, NALLOC, DEF_ALLOC) \
+ do { \
+ size_t _tmp_nalloc; \
+ TYPE *_tmp_arr; \
+\
+ assert((NALLOC) >= (NUSED)); \
+\
+ if((NALLOC) == (NUSED)) { \
+ _tmp_nalloc = (NALLOC) ? (NALLOC) * 2 : (DEF_ALLOC); \
+\
+ if(NULL == (_tmp_arr = (TYPE *)realloc(ARR, _tmp_nalloc * sizeof(TYPE)))) \
+ ERROR("failed to reallocate array"); \
+ (ARR) = _tmp_arr; \
+ (NALLOC) = _tmp_nalloc; \
+ } /* end if */ \
+ } while(0)
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_cmpd_qsort_cb
+ *
+ * Purpose: qsort callback for sorting compound type members by
+ * offset.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5VL_iod_cmpd_qsort_cb(const void *_memb1, const void *_memb2)
+{
+ const H5VL_iod_cmpd_info_t *memb1 = (const H5VL_iod_cmpd_info_t *)_memb1;
+ const H5VL_iod_cmpd_info_t *memb2 = (const H5VL_iod_cmpd_info_t *)_memb2;
+
+ if(memb1->offset < memb2->offset)
+ return -1;
+ else if(memb1->offset > memb2->offset)
+ return 1;
+ else
+ return 0;
+} /* end H5VL_iod_cmpd_qsort_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_type_info_helper
+ *
+ * Purpose: Recursively searches for variable-length datatypes in the
+ * provided type, filling in the fields in type_info.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 18, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5VL_iod_get_type_info_helper(hid_t type_id, H5VL_iod_type_info_t *type_info,
+ size_t offset, size_t *vls_nalloc)
+{
+ hid_t super_type = -1;
+ hsize_t *dims = NULL;
+ size_t num_cmpd_membs = 0;
+ H5VL_iod_cmpd_info_t *cmpd_membs = NULL;
+ H5T_class_t type_class;
+ int i;
+
+ assert(type_info);
+ assert(vls_nalloc);
+
+ /* Get type class */
+ if(H5T_NO_CLASS == (type_class = H5Tget_class(type_id)))
+ ERROR("failed to get datatype class");
+
+ /* Take different actions depending on class */
+ switch(type_class) {
+ case H5T_COMPOUND:
+ {
+ int nmemb;
+
+ /* Get number of members */
+ if((nmemb = H5Tget_nmembers(type_id)) < 0)
+ ERROR("failed to get number of compound datatype members");
+
+ /* Allocate array of members */
+ if(NULL == (cmpd_membs = (H5VL_iod_cmpd_info_t *)malloc((size_t)nmemb * sizeof(H5VL_iod_cmpd_info_t))))
+ ERROR("failed ot allocate array of compound type members");
+
+ /* Get offset and type for all members */
+ for(i = 0; i < nmemb; i++) {
+ cmpd_membs[i].offset = H5Tget_member_offset(type_id, (unsigned)i);
+
+ if((cmpd_membs[i].type_id = H5Tget_member_type(type_id, (unsigned)i)) < 0)
+ ERROR("failed to get compound datatype member type");
+ num_cmpd_membs++;
+ } /* end for */
+
+ /* Sort members by offset */
+ qsort(cmpd_membs, num_cmpd_membs, sizeof(cmpd_membs[0]), H5VL_iod_cmpd_qsort_cb);
+
+ /* Get info for all members */
+ for(i = 0; i < nmemb; i++)
+ if(H5VL_iod_get_type_info_helper(cmpd_membs[i].type_id, type_info, offset + cmpd_membs[i].offset, vls_nalloc) < 0)
+ ERROR("failed to get compound datatype member type info");
+
+ /* Free cmpd_membs. Run in opposite order so if a failure
+ * occurs the error code doesn't try to free types twice */
+ for(i = nmemb - 1; i >= 0; i--) {
+ num_cmpd_membs--;
+ if(H5Tclose(cmpd_membs[i].type_id) < 0)
+ ERROR("failed to close compound member type");
+ } /* end for */
+ free(cmpd_membs);
+ cmpd_membs = NULL;
+
+ break;
+ } /* end block */
+
+ case H5T_ARRAY:
+ {
+ int ndims;
+ size_t array_nelem = 1;
+ size_t orig_num_vls = type_info->num_vls;
+ size_t elem_num_vls;
+ size_t super_type_size;
+ size_t i_size, j_size;
+
+ /* Get array element type */
+ if((super_type = H5Tget_super(type_id)) < 0)
+ ERROR("failed to get array datatype element type");
+
+ /* Get type info for element type (effectively only for the
+ * first element) */
+ if(H5VL_iod_get_type_info_helper(super_type, type_info, offset, vls_nalloc) < 0)
+ ERROR("failed to get array datatype element type info");
+
+ /* If the element type contains any vlens, we must copy the vlen
+ * info for each element in the array */
+ if(type_info->num_vls != orig_num_vls) {
+ assert(type_info->num_vls > orig_num_vls);
+
+ /* Get number of dimensions in array */
+ if((ndims = H5Tget_array_ndims(type_id)) < 0)
+ ERROR("failed to get array datatype number of dimensions");
+
+ /* Allocate array of dimensions */
+ if(NULL == (dims = (hsize_t *)malloc((size_t)ndims * sizeof(hsize_t))))
+ ERROR("failed to allocate array of dimensions");
+
+ /* Get array dimensions */
+ if(H5Tget_array_dims2(type_id, dims) < 0)
+ ERROR("failed to get array datatype dimensions");
+
+ /* Calculate total number of elements */
+ for(i = 0; i < ndims; i++)
+ array_nelem *= (size_t)dims[i];
+
+ /* Get size of element type */
+ if(0 == (super_type_size = H5Tget_size(super_type)))
+ ERROR("failed to get array element type size");
+
+ /* Replicate all vls added during recursion into element
+ * type for each element in the array. Increment ref count
+ * on base types instead of copying. */
+ elem_num_vls = type_info->num_vls;
+ for(i_size = 1; i_size < array_nelem; i_size++)
+ for(j_size = orig_num_vls; j_size < elem_num_vls;
+ j_size++) {
+ H5VL_IOD_ARR_ADD(H5VL_iod_vl_info_t, type_info->vls, type_info->num_vls, *vls_nalloc, 8);
+
+ type_info->vls[type_info->num_vls].offset = type_info->vls[j_size].offset + (i_size * super_type_size);
+ type_info->vls[type_info->num_vls].base_type = type_info->vls[j_size].base_type;
+ if(type_info->vls[type_info->num_vls].base_type)
+ type_info->vls[type_info->num_vls].base_type->rc++;
+ type_info->num_vls++;
+ } /* end for */
+
+ free(dims);
+ dims = NULL;
+ } /* end if */
+
+ if(H5Tclose(super_type) < 0)
+ ERROR("failed to close array datatype element type");
+ super_type = -1;
+
+ break;
+ } /* end block */
+
+ case H5T_VLEN:
+ /* Add vlen to vls array */
+ H5VL_IOD_ARR_ADD(H5VL_iod_vl_info_t, type_info->vls, type_info->num_vls, *vls_nalloc, 8);
+
+ /* Get vlen base type */
+ if((super_type = H5Tget_super(type_id)) < 0)
+ ERROR("failed to get vlen datatype base type");
+
+ /* Set vlen offset in type */
+ type_info->vls[type_info->num_vls].offset = offset;
+
+ /* Allocate type info for base type */
+ if(NULL == (type_info->vls[type_info->num_vls].base_type = (H5VL_iod_type_info_t *)malloc(sizeof(H5VL_iod_type_info_t))))
+ ERROR("failed to allocate vlen datatype base type info");
+ type_info->num_vls++;
+
+ /* Get type info for base type */
+ if(H5VL_iod_get_type_info(super_type, type_info->vls[type_info->num_vls - 1].base_type) < 0)
+ ERROR("failed to get vlen datatype base type info");
+
+ if(H5Tclose(super_type) < 0)
+ ERROR("failed to close vlen datatype base type");
+ super_type = -1;
+
+ break;
+
+ case H5T_STRING:
+ {
+ htri_t is_variable_str;
+
+ /* Check if this string is variable length */
+ if((is_variable_str = H5Tis_variable_str(type_id)) < 0)
+ ERROR("failed to determine if type is variable string");
+
+ if(is_variable_str) {
+ /* Add variable-length string to vls array. Set base_type
+ * to NULL. */
+ H5VL_IOD_ARR_ADD(H5VL_iod_vl_info_t, type_info->vls, type_info->num_vls, *vls_nalloc, 8);
+
+ type_info->vls[type_info->num_vls].offset = offset;
+ type_info->vls[type_info->num_vls].base_type = NULL;
+ type_info->num_vls++;
+
+ break;
+ } /* end if */
+
+ /* Fall through if not variable string */
+ } /* end block */
+
+ default:
+ /* Nothing to do currently */
+ break;
+ } /* end switch */
+
+ return(SUCCEED);
+
+error:
+ if(super_type >= 0)
+ if(H5Tclose(super_type) < 0)
+ PRINT_ERROR("failed to close super type");
+ if(dims)
+ free(dims);
+ if(cmpd_membs) {
+ for(i = 0; i < (int)num_cmpd_membs; i++)
+ if(H5Tclose(cmpd_membs[i].type_id) < 0)
+ PRINT_ERROR("failed to close compound member type");
+ free(cmpd_membs);
+ } /* end if */
+
+ return(FAIL);
+} /* end H5VL_iod_get_type_info_helper() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_type_info
+ *
+ * Purpose: Builds the type_info struct given type_id.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 18, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_get_type_info(hid_t type_id, H5VL_iod_type_info_t *type_info)
+{
+ htri_t found_class;
+
+ /* Initialize struct first, so a call to reset() won't cause problems if
+ * something in this function fails */
+ type_info->num_fl_spans = 0;
+ type_info->fl_spans = NULL;
+ type_info->num_vls = 0;
+ type_info->vls = NULL;
+ type_info->rc = 1;
+ if(0 == (type_info->size = H5Tget_size(type_id)))
+ ERROR("H5Tget_size failed");
+
+ /* Check for a vl or string type */
+ if((found_class = H5Tdetect_class(type_id, H5T_VLEN)) < 0)
+ ERROR("failed to search for vlen type class");
+ if(!found_class)
+ if((found_class = H5Tdetect_class(type_id, H5T_STRING)) < 0)
+ ERROR("failed to search for string type class");
+
+ /* Only need to investigate further if the type contains a vlen or string */
+ if(found_class) {
+ size_t vls_nalloc = 0;
+
+ if(H5VL_iod_get_type_info_helper(type_id, type_info, 0, &vls_nalloc) < 0)
+ ERROR("failed to type info");
+ } /* end if */
+
+ /* If any vlens were found, build fixed-length span info */
+ if(type_info->num_vls) {
+ size_t cur_fl_offset = 0;
+ size_t fl_spans_nalloc = 0;
+ size_t i;
+
+ /* Iterate over all vlens */
+ for(i = 0; i < type_info->num_vls; i++) {
+ /* Check if this vlen left a fixed-length gap before it */
+ assert(type_info->vls[i].offset >= cur_fl_offset);
+ if(type_info->vls[i].offset > cur_fl_offset) {
+ /* Create fixed-length span before vl */
+ H5VL_IOD_ARR_ADD(H5VL_iod_fl_span_t, type_info->fl_spans, type_info->num_fl_spans, fl_spans_nalloc, 2);
+
+ type_info->fl_spans[type_info->num_fl_spans].offset = cur_fl_offset;
+ type_info->fl_spans[type_info->num_fl_spans].size = type_info->vls[i].offset - cur_fl_offset;
+ type_info->num_fl_spans++;
+ } /* end if */
+
+ /* Update cur_fl_offset */
+ cur_fl_offset = type_info->vls[i].offset + (type_info->vls[i].base_type ? sizeof(hvl_t) : sizeof(char *));
+ } /* end for */
+
+ /* Add span at end */
+ assert(type_info->size >= cur_fl_offset);
+ if(type_info->size > cur_fl_offset) {
+ H5VL_IOD_ARR_ADD(H5VL_iod_fl_span_t, type_info->fl_spans, type_info->num_fl_spans, fl_spans_nalloc, 2);
+
+ type_info->fl_spans[type_info->num_fl_spans].offset = cur_fl_offset;
+ type_info->fl_spans[type_info->num_fl_spans].size = type_info->size - cur_fl_offset;
+ type_info->num_fl_spans++;
+ } /* end if */
+ } /* end if */
+
+ return(SUCCEED);
+
+error:
+ H5VL_iod_type_info_reset(type_info);
+
+ return(FAIL);
+} /* end H5VL_iod_get_type_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_type_info_reset
+ *
+ * Purpose: Frees all fields fields in type_info, and anything
+ * referenced by those fields. Does not free type_info.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_type_info_reset(H5VL_iod_type_info_t *type_info)
+{
+ size_t i;
+
+ /* Free fl spans */
+ if(type_info->fl_spans) {
+ free(type_info->fl_spans);
+ type_info->fl_spans = NULL;
+ } /* end if */
+ type_info->num_fl_spans = 0;
+
+ /* Free vls */
+ if(type_info->vls) {
+ /* Recurse into each vl's base type, and free the base type if its rc
+ * reaches 0 */
+ for(i = 0; i < type_info->num_vls; i++)
+ if(type_info->vls[i].base_type
+ && (--type_info->vls[i].base_type->rc == 0)) {
+ H5VL_iod_type_info_reset(type_info->vls[i].base_type);
+ free(type_info->vls[i].base_type);
+ } /* end if */
+
+ free(type_info->vls);
+ type_info->vls = NULL;
+ } /* end if */
+ type_info->num_vls = 0;
+
+ return;
+} /* end H5VL_iod_type_info_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_cs_send_helper
+ *
+ * Purpose: Recursively builds the segments array and array of
+ * variable-length data lengths given buf, type_info and
+ * nelem.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5VL_iod_cs_send_helper(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ size_t *segments_nalloc, char **vl_lengths, size_t *vl_lengths_nused,
+ size_t *vl_lengths_nalloc, void ***free_list, size_t *free_list_len,
+ size_t *free_list_nalloc)
+{
+ _Bool wrapped = FALSE;
+ _Bool wrappable;
+ size_t span_size;
+ size_t i;
+ size_t j;
+
+ assert(nelem > 0);
+
+ if(type_info->vls) {
+ /* Add segments for fixed-length spans */
+ if(type_info->num_fl_spans > 0) {
+ assert(type_info->fl_spans);
+
+ /* Check if we can combine the last span in each element with the first
+ * span in the next */
+ wrappable = ((type_info->fl_spans[type_info->num_fl_spans - 1].offset
+ + type_info->fl_spans[type_info->num_fl_spans - 1].size)
+ == type_info->size) && (type_info->fl_spans[0].offset == 0);
+
+ assert(!(wrappable && (type_info->num_fl_spans == 1)));
+
+ /* Iterate over spans */
+ for(i = 0; i < nelem; i++)
+ for(j = 0; j < type_info->num_fl_spans; j++)
+ if(wrapped)
+ wrapped = FALSE;
+ else {
+ /* Add fixed-length segment to segments array */
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ /* Check if we can wrap this segment */
+ if((j == (type_info->num_fl_spans - 1)) && wrappable
+ && (i != (nelem - 1))) {
+ span_size = type_info->fl_spans[0].size + type_info->fl_spans[j].size;
+ wrapped = TRUE;
+ } /* end if */
+ else
+ span_size = type_info->fl_spans[j].size;
+
+ /* Add segment */
+ (*segments)[*num_segments].address = (hg_ptr_t)(buf + (i * type_info->size) + type_info->fl_spans[j].offset);
+ (*segments)[*num_segments].size = span_size;
+ (*num_segments)++;
+ } /* end else */
+ } /* end if */
+
+ /* Analyze vlens */
+ for(i = 0; i < nelem; i++)
+ for(j = 0; j < type_info->num_vls; j++)
+ if(type_info->vls[j].base_type) {
+ /* Standard vlen */
+ hvl_t vl = *(hvl_t *)(buf + (i * type_info->size) + type_info->vls[j].offset);
+
+ /* Add vl segment length to vl_lengths array */
+ H5VL_IOD_ARR_ADD(char, *vl_lengths, *vl_lengths_nused, *vl_lengths_nalloc, 256);
+ assert(*vl_lengths_nused + 8 <= *vl_lengths_nalloc);
+
+ UINT64ENCODE(&(*vl_lengths)[*vl_lengths_nused], (uint64_t)vl.len);
+ *vl_lengths_nused += 8;
+
+ /* Handle vlen array if present */
+ if(vl.len > 0) {
+ /* Add vlen buffer to free list, if present */
+ if(free_list) {
+ H5VL_IOD_ARR_ADD(void *, *free_list, *free_list_len, *free_list_nalloc, 64);
+
+ (*free_list)[*free_list_len] = vl.p;
+ (*free_list_len)++;
+ } /* end if */
+
+ /* Recurse into vlen data */
+ if(H5VL_iod_cs_send_helper((char *)vl.p, type_info->vls[j].base_type, vl.len, segments, num_segments, segments_nalloc, vl_lengths, vl_lengths_nused, vl_lengths_nalloc, free_list, free_list_len, free_list_nalloc) < 0)
+ ERROR("failed to build segments");
+ } /* end if */
+ } /* end if */
+ else {
+ /* Vlen string */
+ char *vl_s = *(char **)(buf + (i * type_info->size) + type_info->vls[j].offset);
+ uint64_t vl_s_len;
+
+ /* Get size */
+ if(vl_s)
+ vl_s_len = (uint64_t)strlen(vl_s) + 1;
+ else
+ vl_s_len = 0;
+
+ /* Add vl string length to vl_lengths array. Include null
+ * terminator in length to distinguish between NULL pointer
+ * (len = 0) and null string (len = 1) */
+ H5VL_IOD_ARR_ADD(char, *vl_lengths, *vl_lengths_nused, *vl_lengths_nalloc, 256);
+ assert(*vl_lengths_nused + 8 <= *vl_lengths_nalloc);
+
+ UINT64ENCODE(&(*vl_lengths)[*vl_lengths_nused], vl_s_len);
+ *vl_lengths_nused += 8;
+
+ /* Handle the vl string buffer if present */
+ if(vl_s_len > 0) {
+ /* Add vl string buffer to free list, if present */
+ if(free_list) {
+ H5VL_IOD_ARR_ADD(void *, *free_list, *free_list_len, *free_list_nalloc, 64);
+
+ (*free_list)[*free_list_len] = vl_s;
+ (*free_list_len)++;
+ } /* end if */
+
+ /* Add vl string length to segments array, if length is
+ * greater than 1 (including null terminator). Do not
+ * include null terminator in segment length so it is not
+ * transmitted. */
+ if(vl_s_len > 1) {
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ (*segments)[*num_segments].address = (hg_ptr_t)vl_s;
+ (*segments)[*num_segments].size = vl_s_len - 1;
+ (*num_segments)++;
+ } /* end if */
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ else {
+ /* No vlens, just add entire buffer to segments array */
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ (*segments)[*num_segments].address = (hg_ptr_t)buf;
+ (*segments)[*num_segments].size = nelem * type_info->size;
+ (*num_segments)++;
+ } /* end else */
+
+ return(SUCCEED);
+
+error:
+ return(FAIL);
+} /* end H5VL_iod_cs_send_helper() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_create_segments_send
+ *
+ * Purpose: Builds the segments array and array of variable-length
+ * data lengths given buf, type_info and nelem.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_create_segments_send(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ char **vl_lengths, size_t *vl_lengths_size, void ***free_list,
+ size_t *free_list_len)
+{
+ size_t segments_nalloc = 0;
+ size_t vl_lengths_nalloc = 0;
+ size_t free_list_nalloc = 0;
+
+ assert(buf);
+ assert(type_info);
+ assert(type_info->vls);
+ assert(nelem > 0);
+ assert(segments);
+ assert(!*segments);
+ assert(num_segments);
+ assert(*num_segments == 0);
+ assert(vl_lengths);
+ assert(!*vl_lengths);
+ assert(vl_lengths_size);
+ assert(*vl_lengths_size == 0);
+ assert(!free_list == !free_list_len);
+ assert(!free_list || !*free_list);
+ assert(!free_list_len || (*free_list_len == 0));
+
+ /* Call the real (recursive) function */
+ if(H5VL_iod_cs_send_helper(buf, type_info, nelem, segments, num_segments, &segments_nalloc, vl_lengths, vl_lengths_size, &vl_lengths_nalloc, free_list, free_list_len, &free_list_nalloc) < 0)
+ ERROR("failed to build segments");
+
+ return(SUCCEED);
+
+error:
+ return(FAIL);
+} /* end H5VL_iod_create_segments_send() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_cs_recv_helper
+ *
+ * Purpose: Recursively builds the segments array, allocates buffers
+ * for variable-length data, and writes vlen pointers given
+ * (empty) buf, type_info, nelem, and the vl_lengths array.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5VL_iod_cs_recv_helper(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ size_t *segments_nalloc, char *vl_lengths, size_t *vl_lengths_loc,
+ size_t vl_lengths_size, void ***free_list, size_t *free_list_len,
+ size_t *free_list_nalloc)
+{
+ _Bool wrapped = FALSE;
+ _Bool wrappable;
+ size_t span_size;
+ size_t i;
+ size_t j;
+
+ assert(nelem > 0);
+
+ if(type_info->vls) {
+ /* Add segments for fixed-length spans */
+ if(type_info->num_fl_spans > 0) {
+ assert(type_info->fl_spans);
+
+ /* Check if we can combine the last span in each element with the first
+ * span in the next */
+ wrappable = ((type_info->fl_spans[type_info->num_fl_spans - 1].offset
+ + type_info->fl_spans[type_info->num_fl_spans - 1].size)
+ == type_info->size) && (type_info->fl_spans[0].offset == 0);
+
+ assert(!(wrappable && (type_info->num_fl_spans == 1)));
+
+ /* Iterate over spans */
+ for(i = 0; i < nelem; i++)
+ for(j = 0; j < type_info->num_fl_spans; j++)
+ if(wrapped)
+ wrapped = FALSE;
+ else {
+ /* Add fixed-length segment to segments array */
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ /* Check if we can wrap this segment */
+ if((j == (type_info->num_fl_spans - 1)) && wrappable
+ && (i != (nelem - 1))) {
+ span_size = type_info->fl_spans[0].size + type_info->fl_spans[j].size;
+ wrapped = TRUE;
+ } /* end if */
+ else
+ span_size = type_info->fl_spans[j].size;
+
+ /* Add segment */
+ (*segments)[*num_segments].address = (hg_ptr_t)(buf + (i * type_info->size) + type_info->fl_spans[j].offset);
+ (*segments)[*num_segments].size = span_size;
+ (*num_segments)++;
+ } /* end else */
+ } /* end if */
+
+ /* Analyze vlens */
+ for(i = 0; i < nelem; i++)
+ for(j = 0; j < type_info->num_vls; j++)
+ if(type_info->vls[j].base_type) {
+ /* Standard vlen */
+ hvl_t *vl = (hvl_t *)(buf + (i * type_info->size) + type_info->vls[j].offset);
+ uint64_t vl_length;
+
+ /* Retrieve vl segment length from vl_lengths array */
+ if(*vl_lengths_loc + 8 > vl_lengths_size)
+ ERROR("vl_lengths array is too short");
+ UINT64DECODE(&vl_lengths[*vl_lengths_loc], vl_length);
+ *vl_lengths_loc += 8;
+ vl->len = (size_t)vl_length;
+
+ if(vl_length == 0)
+ vl->p = NULL;
+ else {
+ /* Allocate buffer for vlen data */
+ if(NULL == (vl->p = malloc(vl_length * type_info->vls[j].base_type->size)))
+ ERROR("failed to allocate vlen buffer");
+
+ /* Add malloc'ed buffer to free list, if present */
+ if(free_list) {
+ H5VL_IOD_ARR_ADD(void *, *free_list, *free_list_len, *free_list_nalloc, 64);
+
+ (*free_list)[*free_list_len] = vl->p;
+ (*free_list_len)++;
+ } /* end if */
+
+ /* Recurse into vlen data */
+ if(H5VL_iod_cs_recv_helper(vl->p, type_info->vls[j].base_type, (size_t)vl_length, segments, num_segments, segments_nalloc, vl_lengths, vl_lengths_loc, vl_lengths_size, free_list, free_list_len, free_list_nalloc) < 0)
+ ERROR("failed to build segments");
+ } /* end if */
+ } /* end if */
+ else {
+ /* Vlen string */
+ char **vl_s = (char **)(buf + (i * type_info->size) + type_info->vls[j].offset);
+ uint64_t vl_s_len;
+
+ /* Retrieve vl string length from vl_lengths array */
+ if(*vl_lengths_loc + 8 > vl_lengths_size)
+ ERROR("vl_lengths array is too short");
+ UINT64DECODE(&vl_lengths[*vl_lengths_loc], vl_s_len);
+ *vl_lengths_loc += 8;
+
+ if(vl_s_len == 0)
+ *vl_s = NULL;
+ else {
+ /* Allocate buffer for vlen string data */
+ if(NULL == (*vl_s = malloc((size_t)vl_s_len)))
+ ERROR("failed to allocate vlen string buffer");
+
+ /* Add malloc'ed buffer to free list, if present */
+ if(free_list) {
+ H5VL_IOD_ARR_ADD(void *, *free_list, *free_list_len, *free_list_nalloc, 64);
+
+ (*free_list)[*free_list_len] = *vl_s;
+ (*free_list_len)++;
+ } /* end if */
+
+ /* Add vl string to segments array, if length is greater
+ * than 1 (including null terminator) */
+ if(vl_s_len > 1) {
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ (*segments)[*num_segments].address = (hg_ptr_t)*vl_s;
+ (*segments)[*num_segments].size = (size_t)vl_s_len - 1;
+ (*num_segments)++;
+ } /* end if */
+
+ /* Add null terminator */
+ (*vl_s)[vl_s_len - 1] = '\0';
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ else {
+ /* No vlens, just add entire buffer to segments array */
+ H5VL_IOD_ARR_ADD(hg_bulk_segment_t, *segments, *num_segments, *segments_nalloc, 256);
+
+ (*segments)[*num_segments].address = (hg_ptr_t)buf;
+ (*segments)[*num_segments].size = nelem * type_info->size;
+ (*num_segments)++;
+ } /* end else */
+
+ return(SUCCEED);
+
+error:
+ return(FAIL);
+} /* end H5VL_iod_cs_recv_helper() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_create_segments_recv
+ *
+ * Purpose: Builds the segments array, allocates buffers for
+ * variable-length data, and writes vlen pointers given
+ * (empty) buf, type_info, nelem, and the vl_lengths array.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Nov 19, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_create_segments_recv(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ char *vl_lengths, size_t vl_lengths_size, void ***free_list,
+ size_t *free_list_len)
+{
+ size_t segments_nalloc = 0;
+ size_t vl_lengths_loc = 0;
+ size_t free_list_nalloc = 0;
+
+ assert(buf);
+ assert(type_info);
+ assert(type_info->vls);
+ assert(nelem > 0);
+ assert(segments);
+ assert(!*segments);
+ assert(num_segments);
+ assert(*num_segments == 0);
+ assert(vl_lengths);
+ assert(vl_lengths_size > 0);
+ assert(!free_list == !free_list_len);
+ assert(!free_list || !*free_list);
+ assert(!free_list_len || (*free_list_len == 0));
+
+ /* Call the real (recursive) function */
+ if(H5VL_iod_cs_recv_helper(buf, type_info, nelem, segments, num_segments, &segments_nalloc, vl_lengths, &vl_lengths_loc, vl_lengths_size, free_list, free_list_len, &free_list_nalloc) < 0)
+ ERROR("failed to build segments");
+
+ return(SUCCEED);
+
+error:
+ return(FAIL);
+} /* end H5VL_iod_create_segments_recv() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_free_list_free
+ *
+ * Purpose: Frees all pointers on the provided free list and then
+ * frees the free list itself
+ *
+ * Return: void
+ *
+ * Programmer: Neil Fortner
+ * Dec 5, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_free_list_free(void **free_list, size_t free_list_len)
+{
+ size_t i;
+
+ for(i = 0; i < free_list_len; i++)
+ free(free_list[i]);
+ free(free_list);
+} /* end H5VL_iod_free_list_free() */
+
+#ifdef H5_HAVE_EFF
+uint64_t
+H5_checksum_crc64(const void *buf, size_t buf_size)
+{
+ const char *hash_method = "crc64";
+ size_t hash_size;
+ mchecksum_object_t checksum;
+ uint64_t ret_value = 0;
+
+ /* Initialize checksum */
+ mchecksum_init(hash_method, &checksum);
+
+ /* Update checksum */
+ mchecksum_update(checksum, buf, buf_size);
+
+ /* Get size of checksum */
+ hash_size = mchecksum_get_size(checksum);
+
+ assert(hash_size == sizeof(uint64_t));
+
+ /* get checksum value */
+ mchecksum_get(checksum, &ret_value, hash_size, 1);
+
+ /* Destroy checksum */
+ mchecksum_destroy(checksum);
+
+ return ret_value;
+}
+
+uint64_t
+H5_checksum_crc64_segments(hg_bulk_segment_t *segments, size_t count)
+{
+ const char *hash_method = "crc64";
+ size_t hash_size;
+ size_t i;
+ mchecksum_object_t checksum;
+ uint64_t ret_value;
+
+ /* Initialize checksum */
+ mchecksum_init(hash_method, &checksum);
+
+ /* Update checksum */
+ for (i = 0; i < count; i++) {
+ mchecksum_update(checksum, segments[i].address, segments[i].size);
+ }
+
+ /* Get size of checksum */
+ hash_size = mchecksum_get_size(checksum);
+
+ assert(hash_size == sizeof(uint64_t));
+
+ /* get checksum value */
+ mchecksum_get(checksum, &ret_value, hash_size, 1);
+
+ /* Destroy checksum */
+ mchecksum_destroy(checksum);
+
+ return ret_value;
+}
+
+uint64_t
+H5_checksum_crc64_fragments(void **buf, size_t *buf_size, size_t count)
+{
+ const char *hash_method = "crc64";
+ size_t hash_size;
+ size_t i;
+ mchecksum_object_t checksum;
+ uint64_t ret_value;
+
+ /* Initialize checksum */
+ mchecksum_init(hash_method, &checksum);
+
+ /* Update checksum */
+ for (i = 0; i < count; i++) {
+ mchecksum_update(checksum, buf[i], buf_size[i]);
+ }
+
+ /* Get size of checksum */
+ hash_size = mchecksum_get_size(checksum);
+
+ assert(hash_size == sizeof(uint64_t));
+
+ /* get checksum value */
+ mchecksum_get(checksum, &ret_value, hash_size, 1);
+
+ /* Destroy checksum */
+ mchecksum_destroy(checksum);
+
+ return ret_value;
+}
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_common.h b/src/H5VLiod_common.h
new file mode 100644
index 0000000..fa73306
--- /dev/null
+++ b/src/H5VLiod_common.h
@@ -0,0 +1,731 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5VL module
+ */
+#ifndef _H5VLiod_common_H
+#define _H5VLiod_common_H
+
+#include "H5public.h"
+#include "H5FFpublic.h"
+#include "H5VLpublic.h"
+#include "H5VLiod.h" /* Iod VOL plugin */
+
+#ifdef H5_HAVE_EFF
+
+#define NA_UNDEFINED NULL
+#define IOD_OH_UNDEFINED ((uint64_t)0)//(pow(2.0,64.0) - 1)
+#define IOD_ID_UNDEFINED ((uint64_t)(-1))//(pow(2.0,64.0) - 1)
+#define IOD_COUNT_UNDEFINED ((uint64_t)(-1))//(pow(2.0,64.0) - 1)
+#define H5VL_IOD_DEBUG 1
+
+/* Structure for a span of fixed-length data in a type */
+ typedef struct H5VL_iod_fl_span_t {
+ size_t offset; /* Offset of start of span in type */
+ size_t size; /* Size of span */
+} H5VL_iod_fl_span_t;
+
+/* Structure for a variable-length type in a type */
+typedef struct H5VL_iod_vl_info_t {
+ size_t offset; /* Offset of vlen in type */
+ struct H5VL_iod_type_info_t *base_type; /* Type info for vlen base type. Set to NULL if this vlen is a vl string. */
+} H5VL_iod_vl_info_t;
+
+/* Structure containing information about a type to use during I/O */
+typedef struct H5VL_iod_type_info_t {
+ size_t size; /* Size of one element of this type */
+ size_t num_fl_spans; /* Size of fl_spans array */
+ H5VL_iod_fl_span_t *fl_spans; /* Array of spans of fixed-length data in type */
+ size_t num_vls; /* Size of vls array */
+ H5VL_iod_vl_info_t *vls; /* Array of variable-length types in type */
+ size_t rc; /* Number of references to this struct */
+} H5VL_iod_type_info_t;
+
+typedef enum H5VL_iod_state_t {
+ H5VL_IOD_PENDING,
+ H5VL_IOD_COMPLETED,
+ H5VL_IOD_CANCELLED
+} H5VL_iod_state_t;
+
+typedef struct dims_t {
+ int rank;
+ hsize_t *size;
+} dims_t;
+
+typedef struct coords_t {
+ int rank;
+ uint64_t *start_cell;
+ uint64_t *end_cell;
+} coords_t;
+
+typedef struct name_t {
+ size_t size;
+ ssize_t *value_size;
+ char *value;
+} name_t;
+
+typedef struct binary_buf_t {
+ size_t buf_size;
+ void *buf;
+} binary_buf_t;
+
+typedef struct value_t {
+ size_t val_size;
+ void *val;
+} value_t;
+
+typedef struct axe_t {
+ AXE_task_t axe_id;
+ AXE_task_t start_range;
+ size_t count;
+ size_t num_parents;
+ AXE_task_t *parent_axe_ids;
+} axe_t;
+
+typedef struct iod_handles_t {
+ iod_handle_t rd_oh;
+ iod_handle_t wr_oh;
+} iod_handles_t;
+
+#endif /* H5_HAVE_EFF */
+
+H5_DLL int H5VL_iod_get_type_info(hid_t type_id, H5VL_iod_type_info_t *type_info);
+H5_DLL void H5VL_iod_type_info_reset(H5VL_iod_type_info_t *type_info);
+H5_DLL int H5VL_iod_create_segments_send(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ char **vl_lengths, size_t *vl_lengths_nused, void ***free_list,
+ size_t *free_list_len);
+H5_DLL int H5VL_iod_create_segments_recv(char *buf, H5VL_iod_type_info_t *type_info,
+ size_t nelem, hg_bulk_segment_t **segments, size_t *num_segments,
+ char *vl_lengths, size_t vl_lengths_nused, void ***free_list,
+ size_t *free_list_len);
+H5_DLL void H5VL_iod_free_list_free(void **free_list, size_t free_list_len);
+
+#ifdef H5_HAVE_EFF
+
+H5_DLL uint64_t H5_checksum_crc64(const void *buf, size_t buf_size);
+H5_DLL uint64_t H5_checksum_crc64_segments(hg_bulk_segment_t *segments, size_t count);
+H5_DLL uint64_t H5_checksum_crc64_fragments(void **buf, size_t *buf_size, size_t count);
+
+H5_DLL int hg_proc_ret_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_axe_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_size_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_hid_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_htri_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_hbool_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_iod_obj_id_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_iod_handle_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_iod_handles_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_dims_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_axe_ids_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_name_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_value_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_binary_buf_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_linfo_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_oinfo_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_coords_t(hg_proc_t proc, void *data);
+H5_DLL int hg_proc_hrpl_t(hg_proc_t proc, void *data);
+
+MERCURY_GEN_PROC(analysis_execute_in_t,
+ ((axe_t)(axe_info))
+ ((hid_t)(query_id))
+ ((hg_const_string_t)(file_name))
+ ((hg_const_string_t)(obj_name))
+ ((hg_const_string_t)(split_script))
+ ((hg_const_string_t)(combine_script)))
+MERCURY_GEN_PROC(analysis_execute_out_t, ((int32_t)(ret)))
+MERCURY_GEN_PROC(analysis_farm_in_t,
+ ((iod_handle_t)(coh))
+ ((hid_t)(query_id))
+ ((hid_t)(space_id))
+ ((hid_t)(type_id))
+ ((uint64_t)(rtid))
+ ((iod_obj_id_t)(obj_id))
+ ((size_t)(num_cells))
+ ((coords_t)(coords))
+ ((uint32_t)(server_idx))
+ ((hg_const_string_t)(split_script)))
+MERCURY_GEN_PROC(analysis_farm_out_t,
+ ((int32_t)(ret))
+ ((uint64_t)(axe_id))
+ ((uint32_t)(server_idx))
+ ((hg_bulk_t)(bulk_handle))
+ ((hid_t)(type_id))
+ ((size_t)(num_elmts)))
+MERCURY_GEN_PROC(analysis_transfer_in_t,
+ ((hg_bulk_t)(bulk_handle))
+ ((uint64_t)(axe_id))
+ )
+MERCURY_GEN_PROC(analysis_transfer_out_t,
+ ((int32_t)(ret))
+ )
+
+MERCURY_GEN_PROC(eff_init_in_t,
+ ((uint32_t)(proc_num)))
+
+MERCURY_GEN_PROC(file_create_in_t,
+ ((axe_t)(axe_info))
+ ((hg_const_string_t)(name))
+ ((uint32_t)(flags))
+ ((iod_obj_id_t)(root_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((iod_obj_id_t)(oidkv_id))
+ ((uint32_t)(num_peers))
+ ((hid_t)(fapl_id))
+ ((hid_t)(fcpl_id)))
+MERCURY_GEN_PROC(file_create_out_t,
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(root_oh)))
+MERCURY_GEN_PROC(file_open_in_t,
+ ((axe_t)(axe_info))
+ ((hg_const_string_t)(name))
+ ((uint32_t)(flags))
+ ((hbool_t)(acquire))
+ ((hid_t)(fapl_id)))
+MERCURY_GEN_PROC(file_open_out_t,
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(root_oh))
+ ((uint64_t)(kv_oid_index))
+ ((uint64_t)(array_oid_index))
+ ((uint64_t)(blob_oid_index))
+ ((iod_obj_id_t)(root_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((iod_obj_id_t)(oidkv_id))
+ ((uint64_t)(c_version))
+ ((hid_t)(fcpl_id)))
+MERCURY_GEN_PROC(file_close_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(root_oh))
+ ((iod_obj_id_t)(root_id))
+ ((iod_obj_id_t)(max_kv_index))
+ ((iod_obj_id_t)(max_array_index))
+ ((iod_obj_id_t)(max_blob_index)))
+
+MERCURY_GEN_PROC(attr_create_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_attrkv_id))
+ ((iod_obj_id_t)(attr_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((hg_const_string_t)(path))
+ ((hg_const_string_t)(attr_name))
+ ((hid_t)(type_id))
+ ((hid_t)(space_id)))
+MERCURY_GEN_PROC(attr_create_out_t,
+ ((iod_handles_t)(iod_oh)))
+MERCURY_GEN_PROC(attr_open_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_attrkv_id))
+ ((hg_const_string_t)(path))
+ ((hg_const_string_t)(attr_name)))
+MERCURY_GEN_PROC(attr_open_out_t,
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((hid_t)(type_id))
+ ((hid_t)(space_id)))
+MERCURY_GEN_PROC(attr_op_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_attrkv_id))
+ ((hg_const_string_t)(path))
+ ((hg_const_string_t)(attr_name)))
+MERCURY_GEN_PROC(attr_rename_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_attrkv_id))
+ ((hg_const_string_t)(path))
+ ((hg_const_string_t)(old_attr_name))
+ ((hg_const_string_t)(new_attr_name)))
+MERCURY_GEN_PROC(attr_io_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((uint64_t)(checksum))
+ ((hid_t)(space_id))
+ ((hid_t)(type_id))
+ ((hg_bulk_t)(bulk_handle)))
+MERCURY_GEN_PROC(attr_close_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+MERCURY_GEN_PROC(group_create_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(grp_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(gapl_id))
+ ((hid_t)(gcpl_id))
+ ((hid_t)(lcpl_id)))
+MERCURY_GEN_PROC(group_create_out_t,
+ ((iod_handles_t)(iod_oh)))
+MERCURY_GEN_PROC(group_open_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(gapl_id)))
+MERCURY_GEN_PROC(group_open_out_t,
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hid_t)(gcpl_id)))
+MERCURY_GEN_PROC(group_close_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+MERCURY_GEN_PROC(map_create_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(map_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(keytype_id))
+ ((hid_t)(valtype_id))
+ ((hid_t)(mapl_id))
+ ((hid_t)(mcpl_id))
+ ((hid_t)(lcpl_id)))
+MERCURY_GEN_PROC(map_create_out_t,
+ ((iod_handles_t)(iod_oh)))
+MERCURY_GEN_PROC(map_open_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(mapl_id)))
+MERCURY_GEN_PROC(map_open_out_t,
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hid_t)(keytype_id))
+ ((hid_t)(valtype_id))
+ ((hid_t)(mcpl_id)))
+MERCURY_GEN_PROC(map_set_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((hid_t)(key_maptype_id))
+ ((hid_t)(key_memtype_id))
+ ((binary_buf_t)(key))
+ ((hid_t)(val_maptype_id))
+ ((hid_t)(val_memtype_id))
+ ((uint64_t)(val_checksum))
+ ((hg_bulk_t)(val_handle))
+ ((hid_t)(dxpl_id)))
+MERCURY_GEN_PROC(map_get_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((hid_t)(key_maptype_id))
+ ((hid_t)(key_memtype_id))
+ ((binary_buf_t)(key))
+ ((hid_t)(val_maptype_id))
+ ((hid_t)(val_memtype_id))
+ ((hbool_t)(val_is_vl))
+ ((hg_bulk_t)(val_handle))
+ ((size_t)(val_size))
+ ((hid_t)(dxpl_id)))
+MERCURY_GEN_PROC(map_get_out_t,
+ ((int32_t)(ret))
+ ((size_t)(val_size))
+ ((uint64_t)(val_cs)))
+MERCURY_GEN_PROC(map_get_count_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+MERCURY_GEN_PROC(map_op_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((hid_t)(key_maptype_id))
+ ((hid_t)(key_memtype_id))
+ ((binary_buf_t)(key)))
+MERCURY_GEN_PROC(map_close_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+MERCURY_GEN_PROC(dset_create_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(dset_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(dapl_id))
+ ((hid_t)(dcpl_id))
+ ((hid_t)(lcpl_id))
+ ((hid_t)(type_id))
+ ((hid_t)(space_id)))
+MERCURY_GEN_PROC(dset_create_out_t,
+ ((iod_handles_t)(iod_oh)))
+MERCURY_GEN_PROC(dset_open_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(dapl_id)))
+MERCURY_GEN_PROC(dset_open_out_t,
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hid_t)(dcpl_id))
+ ((hid_t)(type_id))
+ ((hid_t)(space_id)))
+MERCURY_GEN_PROC(dset_set_extent_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((dims_t)(dims)))
+MERCURY_GEN_PROC(dset_io_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((hid_t)(dset_type_id))
+ ((hid_t)(mem_type_id))
+ ((hid_t)(space_id))
+ ((hid_t)(dxpl_id))
+ ((uint64_t)(checksum))
+ ((hg_bulk_t)(bulk_handle))
+ ((hg_bulk_t)(vl_len_bulk_handle))
+ ((uint64_t)(axe_id)))
+MERCURY_GEN_PROC(dset_read_out_t,
+ ((int32_t)(ret))
+ ((uint64_t)(cs))
+ ((size_t)(buf_size)))
+MERCURY_GEN_PROC(dset_close_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+MERCURY_GEN_PROC(dtype_commit_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(dtype_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(tapl_id))
+ ((hid_t)(tcpl_id))
+ ((hid_t)(lcpl_id))
+ ((hid_t)(type_id)))
+MERCURY_GEN_PROC(dtype_commit_out_t,
+ ((iod_handles_t)(iod_oh)))
+MERCURY_GEN_PROC(dtype_open_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(name))
+ ((hid_t)(tapl_id)))
+MERCURY_GEN_PROC(dtype_open_out_t,
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hid_t)(tcpl_id))
+ ((hid_t)(type_id)))
+MERCURY_GEN_PROC(dtype_close_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+MERCURY_GEN_PROC(link_create_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((int8_t)(create_type))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(loc_name))
+ ((iod_handles_t)(target_loc_oh))
+ ((iod_obj_id_t)(target_loc_id))
+ ((iod_obj_id_t)(target_mdkv_id))
+ ((hg_const_string_t)(target_name))
+ ((hg_const_string_t)(link_value))
+ ((hid_t)(lapl_id))
+ ((hid_t)(lcpl_id)))
+MERCURY_GEN_PROC(link_move_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((hbool_t)(copy_flag))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(src_loc_oh))
+ ((iod_obj_id_t)(src_loc_id))
+ ((hg_const_string_t)(src_loc_name))
+ ((iod_handles_t)(dst_loc_oh))
+ ((iod_obj_id_t)(dst_loc_id))
+ ((hg_const_string_t)(dst_loc_name))
+ ((hid_t)(lapl_id))
+ ((hid_t)(lcpl_id)))
+MERCURY_GEN_PROC(link_op_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(path)))
+MERCURY_GEN_PROC(link_get_val_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((hg_const_string_t)(path))
+ ((uint64_t)(length)))
+MERCURY_GEN_PROC(link_get_val_out_t,
+ ((int32_t)(ret))
+ ((value_t)(value)))
+
+MERCURY_GEN_PROC(object_token_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((iod_handle_t)(coh))
+ ((iod_obj_id_t)(iod_id))
+ ((uint64_t)(trans_num)))
+MERCURY_GEN_PROC(object_op_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_mdkv_id))
+ ((iod_obj_id_t)(loc_attrkv_id))
+ ((hg_const_string_t)(loc_name)))
+MERCURY_GEN_PROC(object_open_out_t,
+ ((int32_t)(obj_type))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id))
+ ((iod_obj_id_t)(mdkv_id))
+ ((iod_obj_id_t)(attrkv_id))
+ ((hid_t)(cpl_id))
+ ((hid_t)(id1))
+ ((hid_t)(id2)))
+MERCURY_GEN_PROC(object_copy_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(src_loc_oh))
+ ((iod_obj_id_t)(src_loc_id))
+ ((hg_const_string_t)(src_loc_name))
+ ((iod_handles_t)(dst_loc_oh))
+ ((iod_obj_id_t)(dst_loc_id))
+ ((hg_const_string_t)(dst_loc_name))
+ ((hid_t)(ocpypl_id))
+ ((hid_t)(lcpl_id)))
+MERCURY_GEN_PROC(object_set_comment_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((uint64_t)(trans_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_mdkv_id))
+ ((hg_const_string_t)(path))
+ ((hg_const_string_t)(comment)))
+MERCURY_GEN_PROC(object_get_comment_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((iod_handle_t)(coh))
+ ((iod_handles_t)(loc_oh))
+ ((iod_obj_id_t)(loc_id))
+ ((iod_obj_id_t)(loc_mdkv_id))
+ ((hg_const_string_t)(path))
+ ((uint64_t)(length)))
+MERCURY_GEN_PROC(object_get_comment_out_t,
+ ((int32_t)(ret))
+ ((name_t)(name)))
+
+MERCURY_GEN_PROC(rc_acquire_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(c_version))
+ ((hid_t)(rcapl_id)))
+MERCURY_GEN_PROC(rc_acquire_out_t,
+ ((int32_t)(ret))
+ ((uint64_t)(c_version)))
+MERCURY_GEN_PROC(rc_release_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(c_version)))
+MERCURY_GEN_PROC(rc_persist_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(c_version)))
+MERCURY_GEN_PROC(rc_snapshot_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((hg_const_string_t)(snapshot_name))
+ ((uint64_t)(c_version)))
+
+MERCURY_GEN_PROC(tr_start_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(trans_num))
+ ((hid_t)(trspl_id)))
+MERCURY_GEN_PROC(tr_finish_in_t,
+ ((axe_t)(axe_info))
+ ((uint32_t)(cs_scope))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(trans_num))
+ ((hbool_t)(acquire))
+ ((uint32_t)(client_rank))
+ ((iod_obj_id_t)(oidkv_id))
+ ((iod_obj_id_t)(kv_oid_index))
+ ((iod_obj_id_t)(array_oid_index))
+ ((iod_obj_id_t)(blob_oid_index))
+ ((hid_t)(trfpl_id)))
+MERCURY_GEN_PROC(tr_set_depend_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(child_trans_num))
+ ((uint64_t)(parent_trans_num)))
+MERCURY_GEN_PROC(tr_skip_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(start_trans_num))
+ ((uint64_t)(count)))
+MERCURY_GEN_PROC(tr_abort_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint64_t)(trans_num)))
+
+MERCURY_GEN_PROC(prefetch_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((hid_t)(apl_id))
+ ((int32_t)(obj_type))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+MERCURY_GEN_PROC(evict_in_t,
+ ((axe_t)(axe_info))
+ ((iod_handle_t)(coh))
+ ((uint32_t)(cs_scope))
+ ((uint64_t)(rcxt_num))
+ ((hrpl_t)(replica_id))
+ ((hid_t)(apl_id))
+ ((int32_t)(obj_type))
+ ((iod_handles_t)(iod_oh))
+ ((iod_obj_id_t)(iod_id)))
+
+#endif /* H5_HAVE_EFF */
+#endif /* _H5VLiod_common_H */
diff --git a/src/H5VLiod_dset.c b/src/H5VLiod_dset.c
new file mode 100644
index 0000000..4b37995
--- /dev/null
+++ b/src/H5VLiod_dset.c
@@ -0,0 +1,1833 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
+#include "H5Dpkg.h" /* Datasets */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Gprivate.h" /* IDs */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side dataset routines.
+ */
+
+/* User data for VL traverssal */
+typedef struct {
+ iod_handle_t coh;
+ iod_obj_id_t iod_id;
+ iod_handles_t iod_oh;
+ hid_t space_id;
+ uint8_t *buf_ptr;
+ size_t buf_size;
+ size_t nelmts;
+ size_t cur_seg;
+ hg_bulk_segment_t *segments;
+ iod_trans_id_t wtid;
+ iod_trans_id_t rtid;
+} H5VL_iod_server_vl_write_t;
+
+static herr_t
+H5VL__iod_server_vl_data_write(iod_handle_t coh, iod_obj_id_t iod_id, iod_handles_t iod_oh,
+ hid_t space_id, hid_t mem_type_id, hid_t dset_type_id,
+ H5VL_iod_type_info_t type_info, size_t nelmts,
+ size_t num_segments, hg_bulk_segment_t *segments,
+ hid_t dxpl_id, iod_trans_id_t wtid, iod_trans_id_t rtid,
+ na_addr_t source, hg_bulk_t bulk_handle, uint32_t cs_scope);
+
+static herr_t
+H5VL__iod_server_vl_data_read(iod_handle_t coh, AXE_engine_t axe_engine, AXE_task_t axe_id,
+ size_t nelmts, void *buf,
+ hid_t dxpl_id, iod_trans_id_t rtid);
+
+static herr_t
+H5VL__iod_server_vl_data_write_cb(void UNUSED *elem, hid_t type_id, unsigned ndims,
+ const hsize_t *point, void *_udata);
+
+static iod_obj_id_t
+H5VL__iod_get_vl_blob_oid(iod_obj_id_t dset_id, hid_t space_id, const hsize_t *point)
+{
+ hsize_t dims[H5S_MAX_RANK];
+ uint64_t cur;
+ int ndims, i;
+ iod_obj_id_t blob_id = 0;
+
+ ndims = H5Sget_simple_extent_dims(space_id, dims, NULL);
+
+ /* set the BLOB ID algorithmically from the coordinate */
+ cur = 1;
+ for(i=0 ; i<ndims ; i++) {
+ blob_id += cur*point[i];
+ cur *= dims[i];
+ }
+
+ /* copy the last 20 bits of the dataset ID into bits 58->38 of the BLOB ID */
+ for(i=0 ; i<20 ; i++) {
+ (dset_id & (((uint64_t)0x1) << i)) ?
+ (blob_id |= (((uint64_t)0x1) << (38+i+1))) :
+ (blob_id &= ~(((uint64_t)0x1) << (38+i+1)));
+ }
+
+ /* set the BLOB for dset elements ID */
+ blob_id |= (((uint64_t)0x1) << 59);
+
+ /* Set IOD bit parameters for the BLOB ID */
+ IOD_OBJID_SETTYPE(blob_id, IOD_OBJ_BLOB);
+ IOD_OBJID_SETOWNER_APP(blob_id);
+
+ return blob_id;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_create_cb
+ *
+ * Purpose: Creates a dset as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_create_in_t *input = (dset_create_in_t *)op_data->input;
+ dset_create_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t dset_id = input->dset_id; /* The ID of the dataset that needs to be created */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV to be created */
+ iod_obj_id_t attrkv_id = input->attrkv_id; /* The ID of the attirbute KV to be created */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ hid_t space_id = input->space_id;
+ hid_t dcpl_id;
+ iod_handles_t dset_oh, cur_oh;
+ iod_handle_t mdkv_oh;
+ iod_obj_id_t cur_id;
+ const char *name = input->name; /* name of dset including path to create */
+ char *last_comp; /* the name of the dataset obtained from the last component in the path */
+ iod_array_struct_t array; /* IOD array struct describing the dataset's dimensions */
+ scratch_pad sp;
+ iod_ret_t ret = 0;
+ int step = 0;
+ hbool_t enable_checksum = FALSE;
+ H5T_class_t dt_class;
+ iod_hint_list_t *obj_create_hint = NULL;
+ iod_size_t array_dims[H5S_MAX_RANK], current_dims[H5S_MAX_RANK];
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset create %s at %"PRIu64"\n", name, loc_handle.wr_oh.cookie);
+#endif
+
+ if(H5P_DEFAULT == input->dcpl_id)
+ input->dcpl_id = H5Pcopy(H5P_DATASET_CREATE_DEFAULT);
+ dcpl_id = input->dcpl_id;
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_ocpl_enable_checksum(dcpl_id, &enable_checksum) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* the traversal will retrieve the location where the dataset needs
+ to be created. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, wtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Creating Dataset ID %"PRIx64" ",dset_id);
+ fprintf(stderr, "at (OH %"PRIu64" ID %"PRIx64") ", cur_oh.wr_oh.cookie, cur_id);
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum)
+ fprintf(stderr, "with Data integrity ENABLED\n");
+ else
+ fprintf(stderr, "with Data integrity DISABLED\n");
+#endif
+
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ dt_class = H5Tget_class(input->type_id);
+ /* Set the IOD array creation parameters */
+ if(dt_class == H5T_VLEN ||
+ (dt_class == H5T_STRING && H5Tis_variable_str(input->type_id)) )
+ array.cell_size = sizeof(iod_obj_id_t) + sizeof(iod_size_t);
+ else
+ array.cell_size = (uint32_t)H5Tget_size(input->type_id);
+
+ array.num_dims = (uint32_t)H5Sget_simple_extent_ndims(space_id);
+
+ /* Handle Scalar Dataspaces (set rank and current dims size to 1) */
+ if(0 == array.num_dims) {
+ array.num_dims = 1;
+ array.firstdim_max = 1;
+ current_dims[0] = 1;
+ array.current_dims = current_dims;
+ }
+ else {
+ if(H5Sget_simple_extent_dims(space_id, current_dims, array_dims) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimentions' sizes");
+
+ if(H5S_UNLIMITED == array_dims[0]) {
+ array_dims[0] = current_dims[0];
+ array.firstdim_max = IOD_DIMLEN_UNLIMITED;
+ }
+ else {
+ array.firstdim_max = array_dims[0];
+ }
+
+ array.current_dims = current_dims;
+ }
+
+ /* MSC - Add chunking support */
+ array.chunk_dims = NULL;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "now creating the dataset %s cellsize %d num dimensions %d\n",
+ last_comp, array.cell_size, array.num_dims);
+#endif
+
+ /* create the dataset */
+ ret = iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_ARRAY, NULL,
+ &array, &dset_id, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "ret: %d error: %s\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Array object");
+ }
+
+ if (iod_obj_open_write(coh, dset_id, wtid, NULL, &dset_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Dataset for Write");
+ if (iod_obj_open_read(coh, dset_id, wtid, NULL, &dset_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Dataset for Read");
+
+ step ++;
+
+ /* create the attribute KV object for the dataset */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV, NULL, NULL, &attrkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create attribute KV object");
+
+ /* create the metadata KV object for the dataset */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV, NULL, NULL, &mdkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = attrkv_id;
+ sp[2] = IOD_OBJ_INVALID;
+ sp[3] = IOD_OBJ_INVALID;
+
+ /* set scratch pad in dataset */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t sp_cs = 0;
+
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+
+ if (iod_obj_set_scratch(dset_oh.wr_oh, wtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+ else {
+ if (iod_obj_set_scratch(dset_oh.wr_oh, wtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+
+ /* Open Metadata KV object for write */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create scratch pad");
+
+ step ++;
+
+ /* insert plist metadata */
+ if(H5VL_iod_insert_plist(mdkv_oh, wtid, dcpl_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh, wtid, (uint64_t)1,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert object type metadata */
+ if(H5VL_iod_insert_object_type(mdkv_oh, wtid, H5I_DATASET,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* MSC - need to check size of datatype if it fits in
+ entry otherwise create a BLOB*/
+
+ /* insert datatype metadata */
+ if(H5VL_iod_insert_datatype(mdkv_oh, wtid, input->type_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert dataspace metadata */
+ if(H5VL_iod_insert_dataspace(mdkv_oh, wtid, space_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close the Metadata KV object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ step --;
+
+ /* add link in parent group to current object */
+ if(H5VL_iod_insert_new_link(cur_oh.wr_oh, wtid, last_comp,
+ H5L_TYPE_HARD, &dset_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+
+ output.iod_oh.rd_oh.cookie = dset_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = dset_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset create, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(loc_handle.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ /* return an UNDEFINED oh to the client if the operation failed */
+ if(ret_value < 0) {
+ fprintf(stderr, "failed to create Dataset\n");
+
+ if(step == 2) {
+ iod_obj_close(mdkv_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ iod_obj_close(dset_oh.rd_oh, NULL, NULL);
+ iod_obj_close(dset_oh.wr_oh, NULL, NULL);
+ }
+
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ if(obj_create_hint) {
+ free(obj_create_hint);
+ obj_create_hint = NULL;
+ }
+
+ last_comp = (char *)H5MM_xfree(last_comp);
+ input = (dset_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_open_cb
+ *
+ * Purpose: Opens a dataset as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_open_in_t *input = (dset_open_in_t *)op_data->input;
+ dset_open_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ const char *name = input->name; /* name of dset including path to open */
+ iod_obj_id_t dset_id; /* ID of the dataset to open */
+ iod_handles_t dset_oh;
+ iod_handle_t mdkv_oh;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset open %s at (OH %"PRIu64" ID %"PRIx64")\n",
+ name, loc_handle.rd_oh.cookie, loc_id);
+#endif
+
+ /* Traverse Path and open dset */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, name, rtid,
+ cs_scope, &dset_id, &dset_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* open a write handle on the ID. */
+ if (iod_obj_open_write(coh, dset_id, rtid, NULL, &dset_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current dset");
+
+ /* get scratch pad of the dataset */
+ if(iod_obj_get_scratch(dset_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.dcpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE, H5VL_IOD_KEY_OBJ_DATATYPE,
+ cs_scope, NULL, &output.type_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE, H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &output.space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ output.iod_id = dset_id;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+ output.iod_oh.rd_oh.cookie = dset_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = dset_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ fprintf(stderr, "DSET open FAILED\n");
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.space_id = FAIL;
+ output.type_id = FAIL;
+ output.dcpl_id = FAIL;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (dset_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_read_cb
+ *
+ * Purpose: Reads from IOD into the function shipper BDS handle.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_read_cb(AXE_engine_t axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_io_in_t *input = (dset_io_in_t *)op_data->input;
+ dset_read_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t iod_oh = input->iod_oh; /* dset object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* dset ID */
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ hid_t space_id = input->space_id; /* file space selection */
+ hid_t dxpl_id;
+ hid_t src_id = input->dset_type_id; /* the datatype of the dataset's element */
+ hid_t dst_id = input->mem_type_id; /* the memory type of the elements */
+ iod_trans_id_t rtid = input->rcxt_num;
+ //uint32_t cs_scope = input->cs_scope;
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ size_t size, buf_size = 0;
+ void *buf = NULL; /* buffer to hold outgoing data */
+ iod_checksum_t cs = 0; /* checksum value */
+ uint32_t raw_cs_scope;
+ hbool_t is_vl_data;
+ size_t nelmts; /* number of elements selected to read */
+ na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */
+ hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the dset here or if it was already open */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the dataset if we don't have the handle yet */
+ if(iod_oh.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, iod_id, rtid, NULL /*hints*/, &iod_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset Read on OH %"PRIu64" OID %"PRIx64"\n", iod_oh.rd_oh.cookie, iod_id);
+#endif
+
+ if(H5P_DEFAULT == input->dxpl_id)
+ input->dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT);
+ dxpl_id = input->dxpl_id;
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_rawdata_integrity_scope(dxpl_id, &raw_cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* retrieve size of bulk data asked for to be read */
+ size = HG_Bulk_handle_get_size(bulk_handle);
+
+ /* allocate buffer to hold data */
+ if(NULL == (buf = malloc(size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* get the number of points selected */
+ nelmts = (size_t)H5Sget_select_npoints(space_id);
+
+ /* Adjust buffer is type conversion is needed. If the data
+ elements are of variable length, just return that they are in
+ is_vl_data for special processing */
+ if(H5VL__iod_server_adjust_buffer(dst_id, src_id, nelmts, dxpl_id,
+ size, &buf, &is_vl_data, &buf_size) < 0) {
+ fprintf(stderr, "failed to setup write operation");
+ ret_value = FAIL;
+ goto done;
+ }
+
+ if(!is_vl_data) {
+ size_t elmt_size;
+
+ /* If the data is not VL, we can read the data from the array the normal way */
+ elmt_size = H5Tget_size(src_id);
+ if(H5VL__iod_server_final_io(iod_oh.rd_oh, space_id, elmt_size, FALSE,
+ buf, buf_size, (uint64_t)0, raw_cs_scope, rtid) < 0) {
+ fprintf(stderr, "can't read from array object\n");
+ ret_value = FAIL;
+ goto done;
+ }
+
+ {
+ hbool_t flag = FALSE;
+
+ /* do data conversion */
+ if(H5Tconvert(src_id, dst_id, nelmts, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ if(raw_cs_scope) {
+ /* calculate a checksum for the data to be sent */
+ cs = H5_checksum_crc64(buf, size);
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+ /* MSC - check if client requested to corrupt data */
+ if(H5Pget_dxpl_inject_corruption(dxpl_id, &flag) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read property list");
+ if(flag) {
+ fprintf(stderr, "Injecting a bad data value to cause corruption \n");
+ ((char *)buf)[0] = 54;
+ }
+ }
+ }
+ else {
+ /* If the data is of variable length, special access is required */
+ if(H5VL__iod_server_vl_data_read(coh, axe_engine, input->axe_id, nelmts,
+ buf, dxpl_id, rtid) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ }
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_handle_create(buf, size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* free block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't free bds block handle");
+done:
+
+ output.ret = ret_value;
+ output.cs = cs;
+ output.buf_size = buf_size;
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset read, checksum %016lX, sending response to client\n", cs);
+#endif
+
+ input = (dset_io_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ if(buf) {
+ free(buf);
+ buf=NULL;
+ }
+
+ /* close the dataset if we opened it in this routine */
+ if(TRUE == opened_locally) {
+ if(iod_obj_close(iod_oh.rd_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_read_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_get_vl_size_cb
+ *
+ * Purpose: Retrieve the size required to store a selection of VL data.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_get_vl_size_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_io_in_t *input = (dset_io_in_t *)op_data->input;
+ dset_read_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t iod_oh = input->iod_oh; /* dset object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* dset ID */
+ hid_t type_id = input->mem_type_id; /* the datatype of the dataset's element */
+ hid_t space_id = input->space_id; /* file space selection */
+ //hid_t dxpl_id = input->dxpl_id; /* transfer property list */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ size_t buf_size, elmt_size;
+ void *buf = NULL; /* buffer to hold blob IDs and sizes */
+ size_t nelmts; /* number of elements selected to read */
+ uint8_t *buf_ptr = NULL;
+ na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */
+ hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the dset here or if it was already open */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the dataset if we don't have the handle yet */
+ if(iod_oh.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, rtid, NULL /*hints*/, &iod_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ /* get the number of points selected */
+ nelmts = (size_t)H5Sget_select_npoints(space_id);
+ elmt_size = sizeof(iod_obj_id_t) + sizeof(iod_size_t);
+
+ /* allocate buffer to hold blob IDs */
+ if(NULL == (buf = malloc(nelmts * elmt_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* buffer always contains the length of each sequence, so
+ initialize it to the size required to store those lengths */
+ buf_size = nelmts * 8;//sizeof(size_t);
+
+ /* read the array values containing the BLOB IDs and lengths */
+ if(H5VL__iod_server_final_io(iod_oh.rd_oh, space_id, elmt_size, FALSE,
+ buf, buf_size, (uint64_t)0, cs_scope, rtid) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* MSC - create a bulk block handle. Mercury does not support
+ segmented handles yet, so we need a temporrary buffer. */
+ {
+ size_t *temp_buf = NULL;
+ uint8_t *temp_ptr;
+ size_t temp_size;
+ unsigned u;
+ H5VL_iod_type_info_t type_info;
+
+ if(NULL == (temp_buf = (size_t *)malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate size buffer");
+
+ buf_ptr = (uint8_t *)buf;
+ temp_ptr = (uint8_t *)temp_buf;
+
+ /* Get type info */
+ if(H5VL_iod_get_type_info(type_id, &type_info) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to get datatype info");
+
+ assert(1 == type_info.num_vls);
+
+ /* copy just the size of each VL element into the temp buffer */
+ for(u=0 ; u<nelmts ; u++) {
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Element %u with BLOB ID %"PRIx64" size %zu\n",
+ u, *((iod_obj_id_t *)buf_ptr),*((size_t *)(buf_ptr+sizeof(iod_obj_id_t))));
+#endif
+
+ temp_size = *((size_t *)(buf_ptr+sizeof(iod_obj_id_t)));
+
+ if(type_info.vls[0].base_type) {
+ /* Standard vlen */
+ temp_size = temp_size / type_info.vls[0].base_type->size;
+ }
+ else {
+ /* VL string; add space for NULL termination */
+ temp_size ++;
+ }
+
+ UINT64ENCODE(temp_ptr, (uint64_t)temp_size);
+ buf_ptr += elmt_size;
+ }
+
+ H5VL_iod_type_info_reset(&type_info);
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_handle_create(temp_buf, buf_size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* free block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't free bds block handle");
+
+ if(temp_buf) {
+ free(temp_buf);
+ temp_buf = NULL;
+ }
+ }
+
+ op_data->output = buf;
+
+done:
+
+ output.ret = ret_value;
+ output.cs = 0;
+ output.buf_size = buf_size;
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset get vl size (%zu), sending response to client\n", buf_size);
+#endif
+
+ input = (dset_io_in_t *)H5MM_xfree(input);
+
+ /* close the dataset if we opened it in this routine */
+ if(TRUE == opened_locally) {
+ if(iod_obj_close(iod_oh.rd_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_get_vl_size_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_write_cb
+ *
+ * Purpose: Writes from IOD into the function shipper BDS handle.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_io_in_t *input = (dset_io_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t iod_oh = input->iod_oh; /* dset object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* dset ID */
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ hg_bulk_t vl_len_bulk_handle = input->vl_len_bulk_handle; /* bulk handle for vlen length */
+ hid_t space_id = input->space_id; /* file space selection */
+ uint64_t cs = input->checksum; /* checksum recieved for data */
+ hid_t src_id = input->mem_type_id; /* the memory type of the elements */
+ hid_t dst_id = input->dset_type_id; /* the datatype of the dataset's element */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ //uint32_t cs_scope = input->cs_scope;
+ hid_t dxpl_id;
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ size_t size, buf_size;
+ hbool_t is_vl_data;
+ iod_checksum_t data_cs = 0;
+ uint32_t raw_cs_scope;
+ H5VL_iod_type_info_t type_info;
+ void *buf = NULL;
+ size_t nelmts; /* number of elements selected to read */
+ hbool_t flag = FALSE; /* temp flag to indicate whether corruption will be inserted */
+ na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); /* source address to pull data from */
+ hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the dset here or if it was already open */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the dataset if we don't have the handle yet */
+ if(iod_oh.wr_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, wtid, NULL /*hints*/, &iod_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open dataset for write");
+ opened_locally = TRUE;
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset Write on OH %"PRIu64" OID %"PRIx64"\n", iod_oh.wr_oh.cookie, iod_id);
+#endif
+
+ if(H5P_DEFAULT == input->dxpl_id)
+ input->dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT);
+ dxpl_id = input->dxpl_id;
+
+ nelmts = (size_t)H5Sget_select_npoints(space_id);
+
+ /* Get type info */
+ if(H5VL_iod_get_type_info(src_id, &type_info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to get datatype info");
+
+ if(type_info.vls) {
+ hg_bulk_segment_t *segments = NULL;
+ size_t num_segments = 0;
+ char *vl_lengths = NULL;
+ size_t vl_lengths_size = 0;
+ void **free_list = NULL;
+ size_t free_list_len = 0;
+ hg_bulk_t vl_len_handle;
+
+ /* Get size of vl_lengths array and allocate local buffer */
+ vl_lengths_size = HG_Bulk_handle_get_size(vl_len_bulk_handle);
+ if(vl_lengths_size == 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "no vlen lengths sent");
+ if(NULL == (vl_lengths = (char *)malloc(vl_lengths_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate vlen lengths buffer");
+
+ /* Register local memory buffer */
+ if(HG_SUCCESS != HG_Bulk_handle_create(vl_lengths, vl_lengths_size,
+ HG_BULK_READWRITE, &vl_len_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "create vlen bulk handle");
+
+ /* Receive vl length data from client */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, vl_len_bulk_handle,
+ vl_len_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't read vlen lengths bulk data");
+
+ /* Wait for bulk data read to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait for vlen lengths bulk data operation");
+
+ /* Free the bulk handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(vl_len_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free vlen bulk handle");
+
+ if(NULL == (buf = malloc(nelmts * type_info.size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate data buffer");
+
+ /* Create segments from vl lengths */
+ if(H5VL_iod_create_segments_recv((char *)buf, &type_info, nelmts, &segments, &num_segments,
+ vl_lengths, vl_lengths_size, &free_list, &free_list_len) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create segments for bulk data transfer");
+ assert(segments);
+
+#if 1
+ if(H5VL__iod_server_vl_data_write(coh, iod_id, iod_oh, space_id, src_id, dst_id, type_info,
+ nelmts, num_segments, segments, dxpl_id, wtid, rtid,
+ source, bulk_handle, raw_cs_scope) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't write VL data to array object");
+
+#else
+ {
+ int i;
+ size_t j = 0;
+ uint64_t *buf_ptr = (uint64_t *)vl_lengths;
+
+ fprintf(stderr, "Buffer size: %zu\n", nelmts * type_info.size);
+ /* Print VL length DATA */
+ for(i = 0; i < vl_lengths_size/sizeof(size_t); i++) {
+ fprintf(stderr, "Element %d size %lu segment %lu, size %zu\n", i, vl_lengths[j],
+ segments[i].address, segments[i].size);
+ j+=8;
+ } /* end for */
+ }
+
+ /* Register non-contiguous memory segments */
+ if(HG_SUCCESS != HG_Bulk_handle_create_segments(segments, num_segments,
+ HG_BULK_READWRITE, &vl_data_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Bulk Data Handle");
+
+ /* Receive bulk data from client */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, vl_data_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't read bulk data");
+
+ /* Wait for bulk data read to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait for bulk data operation");
+
+ /* Free the bulk handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(vl_data_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free bulk handle");
+
+ {
+ hvl_t *buf_ptr = (hvl_t *)buf;
+ int i, j;
+
+ /* Print VL DATA */
+ for(i = 0; i < 5; i++) {
+ int temp = (int)buf_ptr[i].len;
+
+ fprintf(stderr, "Element %d size %zu: ", i, temp);
+ for(j = 0; j < temp; j++)
+ fprintf(stderr, "%d ",((unsigned int *)buf_ptr[i].p)[j]);
+ fprintf(stderr, "\n");
+ } /* end for */
+ }
+#endif
+
+ /* Free segments */
+ if(segments) {
+ free(segments);
+ segments = NULL;
+ num_segments = 0;
+ } /* end if */
+
+ if(free_list) {
+ H5VL_iod_free_list_free(free_list, free_list_len);
+ free_list = NULL;
+ free_list_len = 0;
+ } /* end if */
+
+ /* Free vl_lengths */
+ if(vl_lengths) {
+ free(vl_lengths);
+ vl_lengths = NULL;
+ vl_lengths_size = 0;
+ }
+ }
+ else {
+ size_t elmt_size;
+
+ /* retrieve size of incoming bulk data */
+ size = HG_Bulk_handle_get_size(bulk_handle);
+
+ /* allocate buffer to hold data */
+ if(NULL == (buf = malloc(size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* create a Mercury block handle for transfer */
+ HG_Bulk_handle_create(buf, size, HG_BULK_READWRITE, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* free the bds block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle");
+
+ /* MSC - check if client requested to corrupt data */
+ if(H5Pget_dxpl_inject_corruption(dxpl_id, &flag) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read property list");
+ if(flag) {
+ ((int *)buf)[0] = 10;
+ }
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_rawdata_integrity_scope(dxpl_id, &raw_cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* verify data if transfer flag is set */
+ if(raw_cs_scope & H5_CHECKSUM_TRANSFER) {
+ data_cs = H5_checksum_crc64(buf, size);
+ if(cs != data_cs) {
+ fprintf(stderr,
+ "Errrr.. Network transfer Data corruption. expecting %"PRIu64", got %"PRIu64"\n",
+ cs, data_cs);
+ ret_value = FAIL;
+ goto done;
+ }
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+
+ buf_size = 0;
+
+ /* Adjust buffer is type conversion is needed. If the data
+ elements are of variable length, just return that they are in
+ is_vl_data for special processing */
+ if(H5VL__iod_server_adjust_buffer(src_id, dst_id, nelmts, dxpl_id,
+ size, &buf, &is_vl_data, &buf_size) < 0) {
+ fprintf(stderr, "failed to setup write operation");
+ ret_value = FAIL;
+ goto done;
+ }
+
+ /* convert data if needed */
+ if(H5Tconvert(src_id, dst_id, nelmts, buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed")
+
+#if 0
+ {
+ int *ptr = (int *)buf;
+
+ fprintf(stderr, "DWRITE Received a buffer of size %zu with values: ", size);
+ for(u=0 ; u<size/sizeof(int) ; ++u)
+ fprintf(stderr, "%d ", ptr[u]);
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ elmt_size = H5Tget_size(dst_id);
+ if(H5VL__iod_server_final_io(iod_oh.wr_oh, space_id, elmt_size, TRUE,
+ buf, buf_size, cs, raw_cs_scope, wtid) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't write to array object");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset write, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+
+ input = (dset_io_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+ H5VL_iod_type_info_reset(&type_info);
+
+ if(buf)
+ free(buf);
+
+ /* close the dataset if we opened it in this routine */
+ if(TRUE == opened_locally) {
+ if(iod_obj_close(iod_oh.wr_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_write_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_set_extent_cb
+ *
+ * Purpose: Set_Extents iod HDF5 dataset.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_set_extent_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_set_extent_in_t *input = (dset_set_extent_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t iod_oh = input->iod_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV object */
+ /* int rank = input->dims.rank; rank of dataset */
+ hbool_t opened_locally = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset Set Extent first dim to %zu\n",
+ (iod_size_t)input->dims.size[0]);
+#endif
+
+ /* open the dataset if we don't have the handle yet */
+ if(iod_oh.wr_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, wtid, NULL /*hints*/, &iod_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ /* extend along the first dimension only */
+ if(iod_array_extend(iod_oh.wr_oh, wtid, (iod_size_t)input->dims.size[0], NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't extend dataset");
+
+ /* modify the dataspace of the dataset */
+ {
+ int rank;
+ hid_t space_id;
+ iod_handle_t mdkv_oh;
+ iod_size_t array_dims[H5S_MAX_RANK], current_dims[H5S_MAX_RANK];
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ /* get the stored dataset dataspace */
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE, H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+
+ if((rank = H5Sget_simple_extent_dims(space_id, current_dims, array_dims)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimentions' sizes");
+
+ /* Modify the size of the data space */
+ if(H5Sset_extent_simple(space_id, rank, input->dims.size, array_dims) < 0)
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space");
+
+ /* insert dataspace metadata */
+ if(H5VL_iod_insert_dataspace(mdkv_oh, wtid, space_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset set_extent, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (dset_set_extent_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the dataset if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_set_extent_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_close_cb
+ *
+ * Purpose: Closes iod HDF5 dataset.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dset_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dset_close_in_t *input = (dset_close_in_t *)op_data->input;
+ iod_handles_t iod_oh = input->iod_oh;
+ //iod_obj_id_t iod_id = input->iod_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start dataset Close %"PRIu64" %"PRIu64"\n",
+ iod_oh.rd_oh.cookie, iod_oh.wr_oh.cookie);
+#endif
+
+ if(iod_obj_close(iod_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Read Array object");
+ if(iod_obj_close(iod_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Write Array object");
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dset close, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (dset_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dset_close_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_final_io
+ *
+ * Read/Write to an IOD array object with an HDF5
+ * selection. This is the normal way to access data given that the
+ * datatype is not of variable length.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__iod_server_final_io(iod_handle_t iod_oh, hid_t space_id, size_t elmt_size,
+ hbool_t write_op, void *buf,
+ size_t UNUSED buf_size, iod_checksum_t cs,
+ uint32_t cs_scope, iod_trans_id_t tid)
+{
+ int ndims, i; /* dataset's rank/number of dimensions */
+ hssize_t num_descriptors = 0, n; /* number of IOD file descriptors needed to describe filespace selection */
+ iod_mem_desc_t *mem_desc; /* memory descriptor used for reading array */
+ iod_array_iodesc_t *file_desc; /* file descriptor used to do IO */
+ iod_hyperslab_t *hslabs = NULL; /* IOD hyperslab generated from HDF5 filespace */
+ iod_checksum_t *cs_list = NULL;
+ uint8_t *buf_ptr = NULL;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the rank of the dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR2(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ /* handle scalar dataspace */
+ if(0 == ndims) {
+ ndims = 1;
+ /* allocate the IOD hyperslab descriptors needed */
+ if(NULL == (hslabs = (iod_hyperslab_t *)malloc(sizeof(iod_hyperslab_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate iod array descriptors");
+
+ hslabs[0].start = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs[0].stride = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs[0].block = (iod_size_t *)malloc(sizeof(iod_size_t));
+ hslabs[0].count = (iod_size_t *)malloc(sizeof(iod_size_t));
+
+ num_descriptors = 1;
+ hslabs[0].start[0] = 0;
+ hslabs[0].count[0] = 1;
+ hslabs[0].block[0] = 1;
+ hslabs[0].stride[0] = 1;
+ }
+ else {
+ /* get the number of decriptors required, i.e. the numbers of iod
+ I/O operations needed */
+ if(H5VL_iod_get_file_desc(space_id, &num_descriptors, NULL) < 0)
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection");
+
+ /* allocate the IOD hyperslab descriptors needed */
+ if(NULL == (hslabs = (iod_hyperslab_t *)malloc
+ (sizeof(iod_hyperslab_t) * (size_t)num_descriptors)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate iod array descriptors");
+
+ for(n=0 ; n<num_descriptors ; n++) {
+ hslabs[n].start = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs[n].stride = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs[n].block = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ hslabs[n].count = (iod_size_t *)malloc(sizeof(iod_size_t) * (size_t)ndims);
+ }
+
+ /* generate the descriptors after allocating the array */
+ if(H5VL_iod_get_file_desc(space_id, &num_descriptors, hslabs) < 0)
+ HGOTO_ERROR2(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection");
+ }
+
+ file_desc = (iod_array_iodesc_t *)hslabs;
+ buf_ptr = (uint8_t *)buf;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ /* allocate cs array */
+ if(NULL == (cs_list = (iod_checksum_t *)calloc
+ (sizeof(iod_checksum_t), (size_t)num_descriptors)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate checksum array");
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO IOD DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+
+ /* set the memory descriptor */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) +
+ (size_t)num_descriptors * sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = (long unsigned)num_descriptors;
+ for(n=0 ; n<num_descriptors ; n++) {
+ hsize_t num_bytes = 0;
+ hsize_t num_elems = 1;
+
+ /* determine how many bytes the current descriptor holds */
+ for(i=0 ; i<ndims ; i++) {
+ num_elems *= (hslabs[n].count[i] * hslabs[n].block[i]);
+ }
+ num_bytes = num_elems * elmt_size;
+
+ mem_desc->frag[n].addr = (void *)buf_ptr;
+ mem_desc->frag[n].len = (iod_size_t)num_bytes;
+
+ if(write_op && (cs_scope & H5_CHECKSUM_IOD))
+ cs_list[n] = H5_checksum_crc64(buf_ptr, (size_t)num_bytes);
+
+#if H5VL_IOD_DEBUG
+ for(i=0 ; i<ndims ; i++) {
+ fprintf(stderr, "Dim %d: start %zu stride %zu block %zu count %zu\n",
+ i, (size_t)file_desc->start[i], (size_t)file_desc->stride[i],
+ (size_t)file_desc->block[i], (size_t)file_desc->count[i]);
+ }
+#endif
+ }
+
+ if(write_op) {
+ /* write to array */
+ ret = iod_array_write(iod_oh, tid, NULL, mem_desc, file_desc, cs_list, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "ret: %d error: %s\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't write to array object");
+ }
+ }
+ else {
+ /* Read from array */
+ ret = iod_array_read(iod_oh, tid, NULL, mem_desc, file_desc, cs_list, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "ret: %d error: %s\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ }
+ }
+
+ /* If this is a read operation, compute checksum for each IOD
+ read, and compare it against checksum returned from IOD */
+ if(!write_op && (cs_scope & H5_CHECKSUM_IOD)) {
+ hsize_t num_bytes = 0;
+ hsize_t num_elems = 1;
+ iod_checksum_t checksum;
+
+ buf_ptr = (uint8_t *)buf;
+
+ for(n=0 ; n<num_descriptors ; n++) {
+ /* determine how many bytes the current descriptor holds */
+ for(i=0 ; i<ndims ; i++)
+ num_elems *= (hslabs[n].count[i] * hslabs[n].block[i]);
+ num_bytes = num_elems * elmt_size;
+
+ checksum = H5_checksum_crc64(buf_ptr, (size_t)num_bytes);
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "IOD checksum = %016lX Checksum Computed = %016lX\n",
+ cs_list[n], checksum);
+#endif
+ if(checksum != cs_list[n]) {
+ fprintf(stderr, "Data Corruption detected when reading\n");
+ ret_value = FAIL;
+ goto done;
+ }
+ buf_ptr += num_bytes;
+ }
+ }
+
+done:
+
+ /* free allocated descriptors */
+ for(n=0 ; n<num_descriptors ; n++) {
+ free(hslabs[n].start);
+ free(hslabs[n].stride);
+ free(hslabs[n].block);
+ free(hslabs[n].count);
+ }
+ if(hslabs) {
+ free(hslabs);
+ hslabs = NULL;
+ }
+ if(cs_list) {
+ free(cs_list);
+ cs_list = NULL;
+ }
+ if(mem_desc) {
+ free(mem_desc);
+ mem_desc = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_final_io() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_vl_data_read
+ *
+ * Iterates over every (variable sized) element in the dataspace
+ * selection and reads it from IOD.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_server_vl_data_read(iod_handle_t coh, AXE_engine_t axe_engine, AXE_task_t axe_id,
+ size_t nelmts, void *buf,
+ hid_t UNUSED dxpl_id, iod_trans_id_t rtid)
+{
+ void *vlen_buf = NULL;
+ uint8_t *vlen_buf_ptr;
+ uint8_t *buf_ptr = (uint8_t *)buf;
+ void *get_size_op_data;
+ op_data_t *op_data = NULL;
+ iod_blob_io_t *io_blob = NULL; /* arary for list I/O */
+ iod_checksum_t *cs_list = NULL;
+ iod_ret_t *ret_list = NULL;
+ iod_handle_t *blob_oh;
+ size_t u, elmt_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* retrieve the buffer that contains the blob IDs and their sizes
+ that was created in the get_size operation */
+ if(AXE_SUCCEED != AXEget_op_data(axe_engine, axe_id, &get_size_op_data))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to get farm op_data");
+ op_data = (op_data_t *)get_size_op_data;
+
+ vlen_buf = op_data->output;
+ vlen_buf_ptr = (uint8_t *)vlen_buf;
+
+ /* allocate a blob list to read the data */
+ if(NULL == (io_blob = (iod_blob_io_t *)malloc(sizeof(iod_blob_io_t) * nelmts)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate blob io array");
+
+ /* allocate an array for the blob OHs */
+ if(NULL == (blob_oh = (iod_handle_t *)malloc(sizeof(iod_handle_t) * nelmts)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate blob io array");
+
+ /* allocate cs array */
+ if(NULL == (cs_list = (iod_checksum_t *)calloc(sizeof(iod_checksum_t), nelmts)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate checksum array");
+
+ /* allocate return array */
+ if(NULL == (ret_list = (iod_ret_t *)calloc(sizeof(iod_ret_t), nelmts)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate return array");
+
+ elmt_size = sizeof(iod_obj_id_t) + sizeof(iod_size_t);
+
+ for(u=0 ; u<nelmts; u++) {
+ size_t blob_size;
+ iod_obj_id_t blob_id;
+ iod_mem_desc_t *mem_desc;
+ iod_blob_iodesc_t *blob_desc;
+
+ blob_id = *((iod_obj_id_t *)vlen_buf_ptr);
+ blob_size = *((size_t *)(vlen_buf_ptr+sizeof(iod_obj_id_t)));
+ vlen_buf_ptr += elmt_size;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Element %zu with BLOB ID %"PRIx64" size %zu\n",
+ u, blob_id, blob_size);
+#endif
+
+ if(iod_obj_open_read(coh, blob_id, rtid, NULL, &blob_oh[u], NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open BLOB for Read");
+
+ /* create memory descriptor for reading */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = (void *)buf_ptr;
+ mem_desc->frag[0].len = blob_size;
+
+ /* create file descriptor for writing */
+ blob_desc = (iod_blob_iodesc_t *)malloc(sizeof(iod_blob_iodesc_t) +
+ sizeof(iod_blob_iofrag_t));
+ blob_desc->nfrag = 1;
+ blob_desc->frag[0].offset = 0;
+ blob_desc->frag[0].len = blob_size;
+
+ /* setup list I/O parameters */
+ io_blob[u].oh = blob_oh[u];
+ io_blob[u].hints = NULL;
+ io_blob[u].mem_desc = mem_desc;
+ io_blob[u].io_desc = blob_desc;
+ io_blob[u].cs = NULL; //MSC - need IOD - &cs_list[u];
+ io_blob[u].ret = &ret_list[u];
+
+ buf_ptr += blob_size;
+ }
+
+ /* Read list IO */
+ if(iod_blob_read_list(coh, rtid, (int)nelmts, io_blob, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from blob objects");
+
+ for(u=0 ; u<nelmts; u++) {
+ if(ret_list[u] < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ free(io_blob[u].mem_desc);
+ free(io_blob[u].io_desc);
+
+ if(iod_obj_close(blob_oh[u], NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+done:
+
+ if(io_blob)
+ free(io_blob);
+ if(blob_oh)
+ free(blob_oh);
+ if(cs_list)
+ free(cs_list);
+ if(ret_list)
+ free(ret_list);
+
+ vlen_buf = NULL;
+ free(op_data->output);
+ op_data->output = NULL;
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__iod_server_vl_data_read */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_vl_data_write
+ *
+ * Iterates over every (variable sized) element in the dataspace
+ * selection and read/write it from IOD.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_server_vl_data_write(iod_handle_t coh, iod_obj_id_t iod_id, iod_handles_t iod_oh,
+ hid_t space_id, hid_t mem_type_id, hid_t UNUSED dset_type_id,
+ H5VL_iod_type_info_t type_info, size_t nelmts,
+ size_t num_segments, hg_bulk_segment_t *segments,
+ hid_t UNUSED dxpl_id, iod_trans_id_t wtid, iod_trans_id_t rtid,
+ na_addr_t source, hg_bulk_t bulk_handle, uint32_t cs_scope)
+{
+ char bogus; /* bogus value to pass to H5Diterate() */
+ H5VL_iod_server_vl_write_t udata;
+ hg_bulk_t vl_data_handle;
+ hg_bulk_request_t bulk_request;
+ size_t buf_size = 0, u;
+ void *buf = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Print VL length DATA */
+ for(u = 0; u < num_segments; u++) {
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Element %zu size %zu \n", u, segments[u].size);
+#endif
+ buf_size += segments[u].size;
+ } /* end for */
+
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate data buffer");
+
+ /* Register local memory buffer */
+ if(HG_SUCCESS != HG_Bulk_handle_create(buf, buf_size, HG_BULK_READWRITE, &vl_data_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "create vlen bulk handle");
+
+ /* Receive vl length data from client */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, vl_data_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't read vlen lengths bulk data");
+
+ /* Wait for bulk data read to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait for vlen lengths bulk data operation");
+
+ /* Free the bulk handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(vl_data_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free vlen bulk handle");
+
+ /* set other parameters needed to do IO */
+ udata.coh = coh;
+ udata.iod_oh = iod_oh;
+ udata.nelmts = nelmts;
+ udata.buf_ptr = (uint8_t *)buf;
+ udata.buf_size = buf_size;
+ udata.wtid = wtid;
+ udata.rtid = rtid;
+ udata.segments = segments;
+ udata.cur_seg = 0;
+ udata.space_id = space_id;
+ udata.iod_id = iod_id;
+
+ /* iterate over every element and read/write it as a BLOB object */
+ if(H5Diterate(&bogus, mem_type_id, space_id, H5VL__iod_server_vl_data_write_cb, &udata) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "failed to compute buffer size");
+
+done:
+ if(buf) {
+ free(buf);
+ buf = NULL;
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+}/* end H5VL__iod_server_vl_data_write */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_vl_data_write_cb
+ *
+ * The callback to the H5Diterate routine called in
+ * H5VL__iod_server_vl_data_write. This will access every element in the
+ * array object and resolves it to a BLOB object. Then the actual data
+ * is read/written from/to the BLOB object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_server_vl_data_write_cb(void UNUSED *elem, hid_t type_id, unsigned ndims,
+ const hsize_t *point, void *_udata)
+{
+ H5VL_iod_server_vl_write_t *udata = (H5VL_iod_server_vl_write_t *)_udata;
+ iod_handle_t coh = udata->coh; /* container handle */
+ //size_t nelmts = udata->nelmts;
+ iod_trans_id_t wtid = udata->wtid;
+ //iod_trans_id_t rtid = udata->rtid;
+ iod_handles_t iod_oh = udata->iod_oh;
+ iod_obj_id_t iod_id = udata->iod_id;
+ iod_obj_id_t blob_id = 0;
+ iod_handle_t blob_oh;
+ iod_hyperslab_t hslab;
+ iod_mem_desc_t *mem_desc; /* memory descriptor used for reading array */
+ iod_array_iodesc_t file_desc; /* file descriptor used to read array */
+ iod_blob_iodesc_t *blob_desc; /* blob descriptor */
+ size_t buf_size;
+ unsigned u;
+ hbool_t created = FALSE;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* read in the point from the array object */
+ hslab.start = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims);
+ hslab.stride = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims);
+ hslab.block = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims);
+ hslab.count = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Writing VL element # %zu\n", udata->cur_seg);
+#endif
+
+ memcpy(hslab.start, point, sizeof(size_t) * ndims);
+ for(u=0 ; u<ndims ; u++) {
+ hslab.stride[u] = 1;
+ hslab.block[u] = 1;
+ hslab.count[u] = 1;
+ }
+ file_desc = hslab;
+
+ /* calculate the BLOB oid for the current coordinate */
+ blob_id = H5VL__iod_get_vl_blob_oid(iod_id, udata->space_id, point);
+
+ /* Attempt to Open the BLOB for write */
+ ret = iod_obj_open_write(coh, blob_id, wtid, NULL, &blob_oh, NULL);
+ /* if the open fails, try and create the BLOB */
+ if(ret != 0) {
+ ret = iod_obj_create(coh, wtid, NULL, IOD_OBJ_BLOB, NULL, NULL, &blob_id, NULL);
+ /* if the BLOB exists now, try to open it again */
+ if(0 == ret || -EEXIST == ret) {
+ if(0 == ret) {
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "created BLOB with ID %"PRIx64"\n", blob_id);
+#endif
+ created = TRUE;
+ }
+ ret = iod_obj_open_write(coh, blob_id, wtid, NULL, &blob_oh, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "ret: %d error: %s %"PRIx64"\n", ret, strerror(-ret), blob_id);
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to open BLOB object");
+ }
+ }
+ else
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Failed to create BLOB object");
+ }
+
+ buf_size = udata->segments[udata->cur_seg].size;
+
+ /* MSC - type conversion ?? */
+
+ /* create memory descriptor for writing */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = (void *)udata->buf_ptr;
+ mem_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* create file descriptor for writing */
+ blob_desc = (iod_blob_iodesc_t *)malloc(sizeof(iod_blob_iodesc_t) +
+ sizeof(iod_blob_iofrag_t));
+ blob_desc->nfrag = 1;
+ blob_desc->frag[0].offset = 0;
+ blob_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* write the VL data to the blob */
+ if(iod_blob_write(blob_oh, wtid, NULL, mem_desc, blob_desc, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object");
+
+ free(mem_desc);
+ free(blob_desc);
+
+ /* close BLOB */
+ if(iod_obj_close(blob_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ if(created) {
+ /* update the array element with the blob_id and sequence length */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t) * 2);
+ mem_desc->nfrag = 2;
+ mem_desc->frag[0].addr = &blob_id;
+ mem_desc->frag[0].len = sizeof(iod_obj_id_t);
+ mem_desc->frag[1].addr = &buf_size;
+ mem_desc->frag[1].len = sizeof(iod_size_t);
+
+ /* MSC - no CS from IOD yet */
+#if 0
+ /* compute checksum of blob ID and sequence length */
+ {
+ void *buffers[2];
+ size_t buf_sizes[2];
+
+ buffers[0] = &blob_id;
+ buf_sizes[0] = sizeof(iod_obj_id_t);
+ buffers[1] = &seq_len;
+ buf_sizes[1] = sizeof(iod_size_t);
+
+ entry_cs = H5_checksum_crc64_fragments(buffers, buf_sizes, 2);
+ }
+#endif
+
+ /* write the blob ID & size to the array element */
+ if(iod_array_write(iod_oh.wr_oh, wtid, NULL,
+ mem_desc, &file_desc, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ free(mem_desc);
+ }
+
+ /* advance buffer pointer */
+ udata->buf_ptr += buf_size;
+ udata->cur_seg ++;
+
+done:
+
+ free(hslab.start);
+ free(hslab.stride);
+ free(hslab.block);
+ free(hslab.count);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}/* end H5VL__iod_server_vl_data_write_cb */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_dtype.c b/src/H5VLiod_dtype.c
new file mode 100644
index 0000000..88639da
--- /dev/null
+++ b/src/H5VLiod_dtype.c
@@ -0,0 +1,513 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side datatype routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_commit_cb
+ *
+ * Purpose: Commits a dtype as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dtype_commit_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dtype_commit_in_t *input = (dtype_commit_in_t *)op_data->input;
+ dtype_commit_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t dtype_id = input->dtype_id; /* The ID of the datatype that needs to be created */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV to be created */
+ iod_obj_id_t attr_id = input->attrkv_id; /* The ID of the attirbute KV to be created */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t dtype_oh, cur_oh;
+ iod_handle_t mdkv_oh;
+ iod_obj_id_t cur_id;
+ const char *name = input->name; /* name of dtype including path to commit */
+ hid_t tcpl_id;
+ char *last_comp; /* the name of the datatype obtained from the last component in the path */
+ size_t buf_size; /* size of the serialized datatype */
+ void *buf;
+ iod_mem_desc_t *mem_desc = NULL; /* memory descriptor used for writing */
+ iod_blob_iodesc_t *file_desc = NULL; /* file descriptor used to write */
+ scratch_pad sp;
+ int step = 0;
+ iod_hint_list_t *obj_create_hint = NULL;
+ hbool_t enable_checksum = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start datatype commit %s at %"PRIu64"\n", name, loc_handle.wr_oh.cookie);
+#endif
+
+ if(H5P_DEFAULT == input->tcpl_id)
+ input->tcpl_id = H5Pcopy(H5P_DATATYPE_CREATE_DEFAULT);
+ tcpl_id = input->tcpl_id;
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_ocpl_enable_checksum(tcpl_id, &enable_checksum) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ /* the traversal will retrieve the location where the datatype needs
+ to be created. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, wtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Creating Datatype ID %"PRIx64" ", dtype_id);
+ fprintf(stderr, "at (OH %"PRIu64" ID %"PRIx64") ", cur_oh.wr_oh.cookie, cur_id);
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum)
+ fprintf(stderr, "with Data integrity ENABLED\n");
+ else
+ fprintf(stderr, "with Data integrity DISABLED\n");
+#endif
+
+ /* create the datatype */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_BLOB,
+ NULL, NULL, &dtype_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create BLOB");
+
+ if (iod_obj_open_read(coh, dtype_id, wtid, NULL, &dtype_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open BLOB");
+ if (iod_obj_open_write(coh, dtype_id, wtid, NULL, &dtype_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open BLOB");
+
+ step ++;
+
+ /* create the metadata KV object for the datatype */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &mdkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* create the attribute KV object for the datatype */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &attr_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create attribute KV object");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = attr_id;
+ sp[2] = IOD_OBJ_INVALID;
+ sp[3] = IOD_OBJ_INVALID;
+
+ /* set scratch pad in datatype */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t sp_cs;
+
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+ if (iod_obj_set_scratch(dtype_oh.wr_oh, wtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+ else {
+ if (iod_obj_set_scratch(dtype_oh.wr_oh, wtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+
+ /* Store Metadata in scratch pad */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open metadata KV object");
+
+ step ++;
+
+ /* determine the buffer size needed to store the encoded type of the datatype */
+ if(H5Tencode(input->type_id, NULL, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode datatype type");
+ if(NULL == (buf = malloc (buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer");
+ /* encode datatype of the datatype */
+ if(H5Tencode(input->type_id, buf, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode datatype type");
+
+ /* create memory descriptor for writing */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = buf;
+ mem_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* create file descriptor for writing */
+ file_desc = (iod_blob_iodesc_t *)malloc(sizeof(iod_blob_iodesc_t) +
+ sizeof(iod_blob_iofrag_t));
+ file_desc->nfrag = 1;
+ file_desc->frag[0].offset = 0;
+ file_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* set scratch pad in datatype */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t dt_cs;
+
+ /* calculate a checksum for the datatype */
+ dt_cs = H5_checksum_crc64(buf, buf_size);
+
+ /* write the serialized type value to the BLOB object */
+ if(iod_blob_write(dtype_oh.wr_oh, wtid, NULL, mem_desc, file_desc,
+ &dt_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object");
+ }
+ else {
+ /* write the serialized type value to the BLOB object */
+ if(iod_blob_write(dtype_oh.wr_oh, wtid, NULL, mem_desc, file_desc, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object");
+ }
+
+ free(mem_desc);
+ free(file_desc);
+
+ /* insert plist metadata */
+ if(H5VL_iod_insert_plist(mdkv_oh, wtid, tcpl_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh, wtid, (uint64_t)1, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert object type metadata */
+ if(H5VL_iod_insert_object_type(mdkv_oh, wtid, H5I_DATATYPE, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* store the datatype size */
+ {
+ iod_kv_t kv;
+
+ kv.key = (void *)H5VL_IOD_KEY_DTYPE_SIZE;
+ kv.key_len = strlen(H5VL_IOD_KEY_DTYPE_SIZE);
+ kv.value_len = sizeof(iod_size_t);
+ kv.value = &buf_size;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ if (iod_kv_set(mdkv_oh, wtid, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(mdkv_oh, wtid, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+ }
+
+ /* close the Metadata KV object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ step --;
+
+ /* add link in parent group to current object */
+ if(H5VL_iod_insert_new_link(cur_oh.wr_oh, wtid, last_comp,
+ H5L_TYPE_HARD, &dtype_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ output.iod_oh.rd_oh.cookie = dtype_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = dtype_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dtype commit, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(loc_handle.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ if(ret_value < 0) {
+ if(step == 2) {
+ iod_obj_close(mdkv_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ iod_obj_close(dtype_oh.rd_oh, NULL, NULL);
+ iod_obj_close(dtype_oh.wr_oh, NULL, NULL);
+ }
+
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ if(obj_create_hint) {
+ free(obj_create_hint);
+ obj_create_hint = NULL;
+ }
+
+ input = (dtype_commit_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+ last_comp = (char *)H5MM_xfree(last_comp);
+ free(buf);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dtype_commit_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_open_cb
+ *
+ * Purpose: Opens a datatype as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dtype_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dtype_open_in_t *input = (dtype_open_in_t *)op_data->input;
+ dtype_open_out_t output;
+ iod_handle_t coh = input->coh; /* container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t dtype_id; /* ID of datatype to open */
+ iod_handles_t dtype_oh;
+ iod_handle_t mdkv_oh;
+ const char *name = input->name; /* name of dtype including path to open */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ size_t buf_size; /* size of serialized datatype */
+ void *buf = NULL;
+ iod_mem_desc_t *mem_desc = NULL; /* memory descriptor used for reading */
+ iod_blob_iodesc_t *file_desc = NULL; /* file descriptor used to write */
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_checksum_t dt_cs = 0, blob_cs = 0;
+ iod_size_t key_size=0, val_size=0;
+ iod_checksum_t iod_cs[2];
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start datatype open %s at (OH %"PRIu64" ID %"PRIx64")\n",
+ name, loc_handle.rd_oh.cookie, loc_id);
+#endif
+
+ /* Traverse Path and open dtype */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, name, rtid,
+ cs_scope, &dtype_id, &dtype_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* open a write handle on the ID. */
+ if (iod_obj_open_write(coh, dtype_id, rtid, NULL, &dtype_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current datatype");
+
+ /* get scratch pad of the datatype */
+ if(iod_obj_get_scratch(dtype_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.tcpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve tcpl");
+
+ val_size = sizeof(iod_size_t);
+ key_size = strlen(H5VL_IOD_KEY_DTYPE_SIZE);
+
+ /* retrieve blob size metadata from scratch pad */
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "datatype size lookup failed");
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate BLOB read buffer");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* create memory descriptor for writing */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) + sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = buf;
+ mem_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* create file descriptor for writing */
+ file_desc = (iod_blob_iodesc_t *)malloc(sizeof(iod_blob_iodesc_t) +
+ sizeof(iod_blob_iofrag_t));
+ file_desc->nfrag = 1;
+ file_desc->frag[0].offset = 0;
+ file_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* read the serialized type value from the BLOB object */
+ if(iod_blob_read(dtype_oh.rd_oh, rtid, NULL, mem_desc, file_desc, &blob_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read from BLOB object");
+
+ if(blob_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* calculate a checksum for the datatype */
+ dt_cs = H5_checksum_crc64(buf, buf_size);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "IOD BLOB checksum = %016lX Checksum Computed = %016lX\n",
+ blob_cs, dt_cs);
+#endif
+ /* Verifty checksum against one given by IOD */
+ if(blob_cs != dt_cs)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "Data Corruption detected when reading datatype");
+ }
+
+ /* decode the datatype */
+ if((output.type_id = H5Tdecode(buf)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to decode datatype");
+
+ free(mem_desc);
+ free(file_desc);
+ free(buf);
+
+ output.iod_id = dtype_id;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+ output.iod_oh.rd_oh.cookie = dtype_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = dtype_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dtype open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.type_id = FAIL;
+ output.tcpl_id = FAIL;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (dtype_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dtype_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_close_cb
+ *
+ * Purpose: Closes iod HDF5 datatype.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_dtype_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ dtype_close_in_t *input = (dtype_close_in_t *)op_data->input;
+ iod_handles_t iod_oh = input->iod_oh;
+ //iod_obj_id_t iod_id = input->iod_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start datatype Close\n");
+#endif
+
+ if(IOD_OH_UNDEFINED == iod_oh.wr_oh.cookie ||
+ IOD_OH_UNDEFINED == iod_oh.rd_oh.cookie) {
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close object with invalid handle");
+ }
+
+ if((iod_obj_close(iod_oh.rd_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Read OH");
+ if((iod_obj_close(iod_oh.wr_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Write OH");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with dtype close, sending response to client\n");
+#endif
+done:
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (dtype_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_dtype_close_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_encdec.c b/src/H5VLiod_encdec.c
new file mode 100644
index 0000000..3d086e1
--- /dev/null
+++ b/src/H5VLiod_encdec.c
@@ -0,0 +1,937 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org>
+ *
+ * Purpose: IOD plugin encode/decode code
+ */
+
+#include "H5FFpublic.h"
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Ppublic.h"
+#include "H5Qpublic.h"
+#include "H5Spublic.h"
+#include "H5VLiod_common.h" /* IOD Common Header */
+
+#ifdef H5_HAVE_EFF
+
+int hg_proc_size_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ size_t *struct_data = (size_t *) data;
+
+ ret = hg_proc_memcpy(proc, struct_data, sizeof(size_t));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_ret_t */
+int hg_proc_ret_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+
+ ret = hg_proc_int32_t(proc, (int32_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ return ret;
+}
+
+int hg_proc_axe_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ size_t u;
+ hg_proc_op_t op;
+ axe_t *struct_data = (axe_t *) data;
+
+ ret = hg_proc_uint64_t(proc, &struct_data->axe_id);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ ret = hg_proc_uint64_t(proc, &struct_data->start_range);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ ret = hg_proc_size_t(proc, &struct_data->count);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ ret = hg_proc_size_t(proc, &struct_data->num_parents);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+ case HG_ENCODE:
+ for(u=0 ; u<struct_data->num_parents ; u++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->parent_axe_ids[u]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_DECODE:
+ if(struct_data->num_parents)
+ struct_data->parent_axe_ids = (uint64_t *)malloc (sizeof(hsize_t) *
+ struct_data->num_parents);
+
+ for(u=0 ; u<struct_data->num_parents ; u++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->parent_axe_ids[u]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_FREE:
+ if(struct_data->num_parents)
+ free(struct_data->parent_axe_ids);
+ break;
+ default:
+ return HG_FAIL;
+ }
+
+ return ret;
+}
+/* Define hg_proc_htri_t */
+int hg_proc_htri_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+
+ ret = hg_proc_int32_t(proc, (int32_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ return ret;
+}
+
+/* Define hg_proc_hbool_t */
+int hg_proc_hbool_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+
+ ret = hg_proc_uint32_t(proc, (uint32_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ return ret;
+}
+
+/* Define hg_proc_iod_handle_t */
+int hg_proc_hrpl_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+
+ ret = hg_proc_uint64_t(proc, (uint64_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_iod_handle_t */
+int hg_proc_iod_handle_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ iod_handle_t *struct_data = (iod_handle_t *)data;
+
+ ret = hg_proc_uint64_t(proc, &struct_data->cookie);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_iod_handles_t */
+int hg_proc_iod_handles_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ iod_handles_t *struct_data = (iod_handles_t *)data;
+
+ ret = hg_proc_iod_handle_t(proc, &struct_data->rd_oh);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ ret = hg_proc_iod_handle_t(proc, &struct_data->wr_oh);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_iod_obj_id_t */
+int hg_proc_iod_obj_id_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ iod_obj_id_t *struct_data = (iod_obj_id_t *)data;
+
+ ret = hg_proc_uint64_t(proc, struct_data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ return ret;
+}
+
+int hg_proc_dims_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ int i;
+ hg_proc_op_t op;
+ dims_t *struct_data = (dims_t *) data;
+
+ ret = hg_proc_int32_t(proc, &struct_data->rank);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+ case HG_ENCODE:
+ for(i=0 ; i<struct_data->rank ; i++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->size[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_DECODE:
+ if(struct_data->rank)
+ struct_data->size = (hsize_t *)malloc (sizeof(hsize_t) * (size_t)struct_data->rank);
+
+ for(i=0 ; i<struct_data->rank ; i++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->size[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_FREE:
+ if(struct_data->rank)
+ free(struct_data->size);
+ break;
+ default:
+ return HG_FAIL;
+ }
+
+ return ret;
+}
+
+int hg_proc_name_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ size_t size;
+ name_t *struct_data = (name_t *) data;
+
+ ret = hg_proc_memcpy(proc, struct_data->value_size, sizeof(ssize_t));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ size = (size_t)(*struct_data->value_size);
+
+ ret = hg_proc_memcpy(proc, &struct_data->size, sizeof(size_t));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ if(NULL != struct_data->value && struct_data->size != 0) {
+ ret = hg_proc_raw(proc, struct_data->value,
+ MIN(size, struct_data->size));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ return ret;
+}
+
+int hg_proc_binary_buf_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ hg_proc_op_t op;
+ binary_buf_t *struct_data = (binary_buf_t *) data;
+
+ ret = hg_proc_raw(proc, &struct_data->buf_size, sizeof(size_t));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+ case HG_ENCODE:
+ if(NULL != struct_data->buf && struct_data->buf_size != 0) {
+ ret = hg_proc_raw(proc, struct_data->buf, struct_data->buf_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_DECODE:
+ if(struct_data->buf_size != 0) {
+ struct_data->buf = malloc (struct_data->buf_size);
+ ret = hg_proc_raw(proc, struct_data->buf, struct_data->buf_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_FREE:
+ if(struct_data->buf_size != 0) {
+ free(struct_data->buf);
+ }
+ break;
+ default:
+ return HG_FAIL;
+ }
+ return ret;
+}
+
+int hg_proc_value_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ value_t *struct_data = (value_t *) data;
+
+ ret = hg_proc_raw(proc, &struct_data->val_size, sizeof(size_t));
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ if(NULL != struct_data->val && struct_data->val_size != 0) {
+ ret = hg_proc_raw(proc, struct_data->val, struct_data->val_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+int hg_proc_linfo_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ H5L_ff_info_t *struct_data = (H5L_ff_info_t *) data;
+
+ ret = hg_proc_int32_t(proc, &struct_data->type);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ if(H5L_TYPE_ERROR == struct_data->type) {
+ return ret;
+ }
+
+ ret = hg_proc_int32_t(proc, &struct_data->cset);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ if(H5L_TYPE_HARD == struct_data->type) {
+ ret = hg_proc_uint64_t(proc, &struct_data->u.address);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ else if(H5L_TYPE_SOFT == struct_data->type) {
+ ret = hg_proc_size_t(proc, &struct_data->u.val_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ else {
+ HG_ERROR_DEFAULT("Proc error - link type not supported");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+int hg_proc_oinfo_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ H5O_ff_info_t *struct_data = (H5O_ff_info_t *) data;
+
+ ret = hg_proc_uint64_t(proc, &struct_data->addr);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ ret = hg_proc_int32_t(proc, &struct_data->type);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ ret = hg_proc_uint32_t(proc, &struct_data->rc);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ ret = hg_proc_uint64_t(proc, &struct_data->num_attrs);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_plist_t */
+static int hg_proc_plist_t(hg_proc_t proc, hid_t *data)
+{
+ int ret = HG_SUCCESS;
+ size_t plist_size = 0;
+ void *buf = NULL;
+ hid_t plist_id;
+ hg_proc_op_t op;
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+
+ case HG_ENCODE:
+ plist_id = *data;
+ /*
+ if(H5P_FILE_CREATE_DEFAULT != plist_id && H5P_GROUP_CREATE_DEFAULT != plist_id &&
+ H5P_LINK_CREATE_DEFAULT != plist_id && H5P_DATASET_CREATE_DEFAULT != plist_id &&
+ H5P_FILE_ACCESS_DEFAULT != plist_id && H5P_GROUP_ACCESS_DEFAULT != plist_id &&
+ H5P_ATTRIBUTE_CREATE_DEFAULT != plist_id && H5P_OBJECT_COPY_DEFAULT != plist_id &&
+ H5P_DATASET_ACCESS_DEFAULT != plist_id && H5P_DATASET_XFER_DEFAULT != plist_id &&
+ H5P_DATATYPE_CREATE_DEFAULT != plist_id && H5P_DATATYPE_ACCESS_DEFAULT != plist_id &&
+ H5P_LINK_ACCESS_DEFAULT != plist_id && H5P_RC_ACQUIRE_DEFAULT != plist_id &&
+ H5P_TR_START_DEFAULT != plist_id && H5P_TR_FINISH_DEFAULT != plist_id) */
+ if(H5P_OBJECT_COPY_DEFAULT != plist_id) {
+ if(H5Pencode(plist_id, NULL, &plist_size) < 0) {
+ HG_ERROR_DEFAULT("PLIST encode Proc error");
+ return HG_FAIL;
+ }
+ }
+
+ if(plist_size) {
+ buf = H5MM_malloc(plist_size);
+ if(H5Pencode(plist_id, buf, &plist_size) < 0) {
+ HG_ERROR_DEFAULT("PLIST encode Proc error");
+ return HG_FAIL;
+ }
+ }
+
+ ret = hg_proc_size_t(proc, &plist_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(plist_size) {
+ ret = hg_proc_raw(proc, buf, plist_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ H5MM_xfree(buf);
+ }
+ break;
+ case HG_DECODE:
+ ret = hg_proc_size_t(proc, &plist_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(plist_size) {
+ buf = H5MM_malloc(plist_size);
+ ret = hg_proc_raw(proc, buf, plist_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if((plist_id = H5Pdecode(buf)) < 0) {
+ HG_ERROR_DEFAULT("PLIST decode Proc error");
+ return HG_FAIL;
+ }
+ H5MM_xfree(buf);
+ }
+ else
+ plist_id = H5P_DEFAULT;
+
+ *data = plist_id;
+ break;
+ case HG_FREE:
+ plist_id = *data;
+ if(plist_id != H5P_DEFAULT) {
+ if(H5Pclose(plist_id) < 0) {
+ HG_ERROR_DEFAULT("PLIST free Proc error");
+ return HG_FAIL;
+ }
+ }
+ break;
+ default:
+ HG_ERROR_DEFAULT("PLIST unsupported op Proc error");
+ }
+ return ret;
+}
+
+/* Define hg_proc_dtype_t */
+static int hg_proc_dtype_t(hg_proc_t proc, hid_t *data)
+{
+ int ret = HG_SUCCESS;
+ size_t dtype_size = 0;
+ void *buf = NULL;
+ hid_t dtype_id;
+ hg_proc_op_t op;
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+
+ case HG_ENCODE:
+ dtype_id = *data;
+ if(H5Tencode(dtype_id, NULL, &dtype_size) < 0) {
+ HG_ERROR_DEFAULT("DTYPE encode Proc error");
+ return HG_FAIL;
+ }
+ if(dtype_size) {
+ buf = H5MM_malloc(dtype_size);
+ if(H5Tencode(dtype_id, buf, &dtype_size) < 0) {
+ HG_ERROR_DEFAULT("DTYPE encode Proc error");
+ return HG_FAIL;
+ }
+ }
+
+ ret = hg_proc_size_t(proc, &dtype_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(dtype_size) {
+ ret = hg_proc_raw(proc, buf, dtype_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ H5MM_xfree(buf);
+ }
+ break;
+ case HG_DECODE:
+ ret = hg_proc_size_t(proc, &dtype_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(dtype_size) {
+ buf = H5MM_malloc(dtype_size);
+ ret = hg_proc_raw(proc, buf, dtype_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if((dtype_id = H5Tdecode(buf)) < 0) {
+ HG_ERROR_DEFAULT("DTYPE decode Proc error");
+ return HG_FAIL;
+ }
+ H5MM_xfree(buf);
+ }
+ *data = dtype_id;
+ break;
+ case HG_FREE:
+ if(H5Tclose(*data) < 0) {
+ HG_ERROR_DEFAULT("DTYPE free Proc error");
+ return HG_FAIL;
+ }
+ break;
+ default:
+ HG_ERROR_DEFAULT("DTYPE unsupported op Proc error");
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_dspace_t */
+static int hg_proc_dspace_t(hg_proc_t proc, hid_t *data)
+{
+ int ret = HG_SUCCESS;
+ size_t dspace_size = 0;
+ void *buf = NULL;
+ hid_t dspace_id;
+ hg_proc_op_t op;
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+
+ case HG_ENCODE:
+ dspace_id = *data;
+ if(H5Sencode(dspace_id, NULL, &dspace_size) < 0) {
+ HG_ERROR_DEFAULT("DSPACE encode Proc error");
+ return HG_FAIL;
+ }
+ if(dspace_size) {
+ buf = H5MM_malloc(dspace_size);
+ if(H5Sencode(dspace_id, buf, &dspace_size) < 0) {
+ HG_ERROR_DEFAULT("DSPACE encode Proc error");
+ return HG_FAIL;
+ }
+ }
+
+ ret = hg_proc_size_t(proc, &dspace_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(dspace_size) {
+ ret = hg_proc_raw(proc, buf, dspace_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ H5MM_xfree(buf);
+ }
+ break;
+ case HG_DECODE:
+ ret = hg_proc_size_t(proc, &dspace_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(dspace_size) {
+ buf = H5MM_malloc(dspace_size);
+ ret = hg_proc_raw(proc, buf, dspace_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if((dspace_id = H5Sdecode(buf)) < 0) {
+ HG_ERROR_DEFAULT("DSPACE decode Proc error");
+ return HG_FAIL;
+ }
+ H5MM_xfree(buf);
+ }
+ *data = dspace_id;
+ break;
+ case HG_FREE:
+ if(H5Sclose(*data) < 0) {
+ HG_ERROR_DEFAULT("DSPACE free Proc error");
+ return HG_FAIL;
+ }
+ break;
+ default:
+ HG_ERROR_DEFAULT("DSPACE unsupported op Proc error");
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_query_t */
+static int hg_proc_query_t(hg_proc_t proc, hid_t *data)
+{
+ int ret = HG_SUCCESS;
+ size_t query_size = 0;
+ void *buf = NULL;
+ hid_t query_id;
+ hg_proc_op_t op;
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+
+ case HG_ENCODE:
+ query_id = *data;
+ if(H5Qencode(query_id, NULL, &query_size) < 0) {
+ HG_ERROR_DEFAULT("QUERY encode Proc error");
+ return HG_FAIL;
+ }
+ if(query_size) {
+ buf = H5MM_malloc(query_size);
+ if(H5Qencode(query_id, buf, &query_size) < 0) {
+ HG_ERROR_DEFAULT("QUERY encode Proc error");
+ return HG_FAIL;
+ }
+ }
+
+ ret = hg_proc_size_t(proc, &query_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(query_size) {
+ ret = hg_proc_raw(proc, buf, query_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ H5MM_xfree(buf);
+ }
+ break;
+ case HG_DECODE:
+ ret = hg_proc_size_t(proc, &query_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if(query_size) {
+ buf = H5MM_malloc(query_size);
+ ret = hg_proc_raw(proc, buf, query_size);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ if((query_id = H5Qdecode(buf)) < 0) {
+ HG_ERROR_DEFAULT("QUERY decode Proc error");
+ return HG_FAIL;
+ }
+ H5MM_xfree(buf);
+ }
+ *data = query_id;
+ break;
+ case HG_FREE:
+ if(H5Qclose(*data) < 0) {
+ HG_ERROR_DEFAULT("QUERY free Proc error");
+ return HG_FAIL;
+ }
+ break;
+ default:
+ HG_ERROR_DEFAULT("QUERY unsupported op Proc error");
+ }
+
+ return ret;
+}
+
+/* Define hg_proc_hid_t */
+int hg_proc_hid_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ hid_t id = *((hid_t *)data);
+ hg_proc_op_t op;
+ H5I_type_t type;
+
+ op = hg_proc_get_op(proc);
+
+ if (HG_ENCODE == op || HG_FREE == op) {
+ if(FAIL == id)
+ type = H5I_UNINIT;
+ else
+ type = H5Iget_type(id);
+ }
+ ret = hg_proc_int32_t(proc, &type);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ switch(type) {
+ case H5I_DATASPACE:
+ ret = hg_proc_dspace_t(proc, (hid_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ break;
+ case H5I_DATATYPE:
+ ret = hg_proc_dtype_t(proc, (hid_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ break;
+ case H5I_GENPROP_LST:
+ ret = hg_proc_plist_t(proc, (hid_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ break;
+ case H5I_QUERY:
+ ret = hg_proc_query_t(proc, (hid_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ break;
+ case H5I_UNINIT:
+ ret = hg_proc_int32_t(proc, (hid_t *)data);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ break;
+ default:
+ HG_ERROR_DEFAULT("Unsupported hid_t - Proc error");
+ ret = HG_FAIL;
+ break;
+ }
+ return ret;
+}
+
+int hg_proc_coords_t(hg_proc_t proc, void *data)
+{
+ int ret = HG_SUCCESS;
+ int i;
+ hg_proc_op_t op;
+ coords_t *struct_data = (coords_t *) data;
+
+ ret = hg_proc_int32_t(proc, &struct_data->rank);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+
+ op = hg_proc_get_op(proc);
+
+ switch(op) {
+ case HG_ENCODE:
+ for(i=0 ; i<struct_data->rank ; i++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->start_cell[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ ret = hg_proc_uint64_t(proc, &struct_data->end_cell[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_DECODE:
+ if(struct_data->rank) {
+ struct_data->start_cell = (uint64_t *)malloc (sizeof(uint64_t) * (size_t)struct_data->rank);
+ struct_data->end_cell = (uint64_t *)malloc (sizeof(uint64_t) * (size_t)struct_data->rank);
+ }
+
+ for(i=0 ; i<struct_data->rank ; i++) {
+ ret = hg_proc_uint64_t(proc, &struct_data->start_cell[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ ret = hg_proc_uint64_t(proc, &struct_data->end_cell[i]);
+ if (ret != HG_SUCCESS) {
+ HG_ERROR_DEFAULT("Proc error");
+ ret = HG_FAIL;
+ return ret;
+ }
+ }
+ break;
+ case HG_FREE:
+ if(struct_data->rank) {
+ free(struct_data->start_cell);
+ free(struct_data->end_cell);
+ }
+ break;
+ default:
+ return HG_FAIL;
+ }
+
+ return ret;
+}
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_file.c b/src/H5VLiod_file.c
new file mode 100644
index 0000000..775efdf
--- /dev/null
+++ b/src/H5VLiod_file.c
@@ -0,0 +1,782 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * February, 2013
+ *
+ * Purpose: The IOD plugin server side file routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_create_cb
+ *
+ * Purpose: Creates a file as a iod HDF5 file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_file_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ file_create_in_t *input = (file_create_in_t *)op_data->input;
+ file_create_out_t output;
+ unsigned num_peers = input->num_peers; /* the number of peers participating in creation */
+ iod_obj_id_t root_id = input->root_id;
+ iod_obj_id_t mdkv_id = input->mdkv_id;
+ iod_obj_id_t attrkv_id = input->attrkv_id;
+ iod_obj_id_t oidkv_id = input->oidkv_id;
+ hid_t fcpl_id;
+ unsigned int mode; /* create mode */
+ iod_handle_t coh; /* container handle */
+ iod_handles_t root_oh; /* root object handle */
+ iod_handle_t mdkv_oh; /* metadata object handle for KV to store file's metadata */
+ iod_ret_t ret, root_ret;
+ iod_trans_id_t first_tid = 0;
+ uint32_t cs_scope = 0;
+ iod_hint_list_t *con_open_hint = NULL;
+ iod_hint_list_t *obj_create_hint = NULL;
+ hbool_t enable_checksum = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start file create %s ", input->name);
+ fprintf(stderr, "with MDKV %"PRIx64" ", mdkv_id),
+ fprintf(stderr, "with attrKV %"PRIx64"\n", attrkv_id),
+ fprintf(stderr, "with OIDKV %"PRIx64"\n", oidkv_id),
+#endif
+
+ /* convert HDF5 flags to IOD flags */
+ mode = (input->flags&H5F_ACC_RDWR) ? IOD_CONT_RW : IOD_CONT_R;
+ if (input->flags&H5F_ACC_CREAT)
+ mode |= IOD_CONT_CREATE;
+
+ if(H5P_DEFAULT == input->fcpl_id)
+ input->fcpl_id = H5Pcopy(H5P_FILE_CREATE_DEFAULT);
+ fcpl_id = input->fcpl_id;
+
+ if(H5Pget_metadata_integrity_scope(input->fapl_id, &cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ if(H5Pget_ocpl_enable_checksum(fcpl_id, &enable_checksum) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* scratch pad integrity in the container */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ con_open_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ con_open_hint->num_hint = 1;
+ con_open_hint->hint[0].key = "iod_hint_co_scratch_cksum";
+ }
+
+ /* root group integrity */
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ /* Create the Container */
+ ret = iod_container_open(input->name, con_open_hint, mode, &coh, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't create container");
+
+ ret = iod_trans_start(coh, &first_tid, NULL, num_peers, IOD_TRANS_W, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't start transaction");
+
+ /* create the root group */
+ root_ret = iod_obj_create(coh, first_tid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &root_id, NULL);
+ if(0 == root_ret || -EEXIST == root_ret) {
+ /* root group has been created, open it */
+ ret = iod_obj_open_write(coh, root_id, first_tid, NULL, &root_oh.wr_oh, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't open root group for write");
+ ret = iod_obj_open_read(coh, root_id, first_tid, NULL, &root_oh.rd_oh, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't open root group for read");
+ }
+ else {
+ HGOTO_ERROR_IOD(ret, FAIL, "can't create root group");
+ }
+
+ /* for the process that succeeded in creating the group, create
+ the scratch pad for it too. */
+ if(0 == root_ret) {
+ scratch_pad sp;
+ iod_kv_t kv;
+ uint64_t value = 1;
+
+ /* create the metadata KV object for the root group */
+ ret = iod_obj_create(coh, first_tid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &mdkv_id, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't create metadata KV object");
+
+ /* create the attribute KV object for the root group */
+ ret = iod_obj_create(coh, first_tid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &attrkv_id, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't create attribute KV object");
+
+ /* create the KV object to hold each client's indexes for
+ object OIDs after each trans_finish and file_close */
+ ret = iod_obj_create(coh, first_tid, NULL, IOD_OBJ_KV, NULL, NULL, &oidkv_id, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't create array for OID indexes");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = attrkv_id;
+ sp[2] = oidkv_id;
+ sp[3] = IOD_OBJ_INVALID;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t sp_cs;
+
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+
+ /* set scratch pad in root group */
+ ret = iod_obj_set_scratch(root_oh.wr_oh, first_tid, &sp, &sp_cs, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set scratch pad");
+ }
+ else {
+ ret = iod_obj_set_scratch(root_oh.wr_oh, first_tid, &sp, NULL, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set scratch pad");
+ }
+
+ /* Store Metadata in scratch pad */
+ ret = iod_obj_open_write(coh, input->mdkv_id, first_tid, NULL, &mdkv_oh, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't open metadata KV");
+
+ /* insert plist metadata */
+ if(H5VL_iod_insert_plist(mdkv_oh, first_tid, fcpl_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't insert link count KV value");
+
+ kv.value = &value;
+ kv.value_len = sizeof(uint64_t);
+
+ kv.key = (void *)H5VL_IOD_KEY_KV_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_KV_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, cs, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, NULL, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+
+ kv.key = (void *)H5VL_IOD_KEY_ARRAY_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_ARRAY_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, cs, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, NULL, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+
+ kv.key = (void *)H5VL_IOD_KEY_BLOB_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_BLOB_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, cs, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ ret = iod_kv_set(mdkv_oh, first_tid, NULL, &kv, NULL, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't set KV pair in parent");
+ }
+
+ ret = iod_obj_close(mdkv_oh, NULL, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't close root object handle");
+ }
+
+ /* Finish the transaction */
+ ret = iod_trans_finish(coh, first_tid, NULL, 0, NULL);
+ if(ret < 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't finish transaction 0");
+
+ output.coh.cookie = coh.cookie;
+ output.root_oh.rd_oh = root_oh.rd_oh;
+ output.root_oh.wr_oh = root_oh.wr_oh;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with file create coh: %"PRIu64" root rd: %"PRIu64" wr: %"PRIu64"\n",
+ coh.cookie, root_oh.rd_oh.cookie, root_oh.wr_oh.cookie);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.coh.cookie = IOD_OH_UNDEFINED;
+ output.root_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.root_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+ }
+
+ input = (file_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ if(con_open_hint) {
+ free(con_open_hint);
+ con_open_hint = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_file_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_open_cb
+ *
+ * Purpose: Opens a file as a iod HDF5 file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_file_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ file_open_in_t *input = (file_open_in_t *)op_data->input;
+ file_open_out_t output;
+ unsigned int mode = input->flags; /* File Open mode */
+ hbool_t acquire = input->acquire;
+ iod_handle_t coh; /* container handle */
+ iod_handles_t root_oh; /* root object handle */
+ iod_handle_t mdkv_oh; /* metadata object handle for KV to store file's metadata */
+ iod_handle_t oidkv_oh; /* object handle for KV to store file's OID indexes*/
+ int num_entries;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_cont_trans_stat_t *tids = NULL;
+ iod_trans_id_t rtid;
+ iod_size_t key_size = 0, val_size = 0;
+ uint32_t cs_scope = 0;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start file open %s %d %d\n", input->name, input->flags, input->fapl_id);
+#endif
+
+ if(H5F_ACC_RDWR == mode)
+ mode = IOD_CONT_RW;
+ else if(H5F_ACC_RDONLY == mode)
+ mode = IOD_CONT_R;
+ else
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "invalid mode");
+
+ /* MSC - can't open file read only since IOD will fail when object
+ are opened for write */
+ if(mode == IOD_CONT_R)
+ mode = IOD_CONT_RW;
+
+ if(H5Pget_metadata_integrity_scope(input->fapl_id, &cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* open the container */
+ if(iod_container_open(input->name, NULL, mode, &coh, NULL /*event*/))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open file");
+
+ if(iod_query_cont_trans_stat(coh, &tids, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get container tids status");
+
+ rtid = tids->latest_rdable;
+
+ if(iod_free_cont_trans_stat(coh, tids) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free container transaction status object");
+
+ if(iod_trans_start(coh, &rtid, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't start transaction");
+
+ /* open the root group */
+ if ((ret = iod_obj_open_read(coh, ROOT_ID, rtid, NULL, &root_oh.rd_oh, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open root object for read");
+ }
+ if ((ret = iod_obj_open_write(coh, ROOT_ID, rtid, NULL, &root_oh.wr_oh, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open root object for write");
+ }
+ /* get scratch pad of root group */
+ if(iod_obj_get_scratch(root_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for root object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV object */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MD KV");
+
+ /* retrieve all metadata from scratch pad */
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.fcpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve fcpl");
+
+ /* open the OID indexes KV object */
+ if (iod_obj_open_read(coh, sp[2], rtid, NULL, &oidkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open OID KV");
+
+ ret = iod_kv_get_num(oidkv_oh, rtid, &num_entries, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't get number of KV entries");
+
+ val_size = sizeof(uint64_t);
+
+ /* This was not a clean shutdown, so gather all the oid indexes
+ and compute the max */
+ if(0 != num_entries) {
+ iod_kv_params_t *kvs = NULL;
+ iod_kv_t *kv = NULL;
+ iod_checksum_t *oid_cs = NULL;
+ iod_ret_t *oid_ret = NULL;
+ int i;
+
+ kvs = (iod_kv_params_t *)malloc(sizeof(iod_kv_params_t) * (size_t)num_entries);
+ kv = (iod_kv_t *)malloc(sizeof(iod_kv_t) * (size_t)num_entries);
+ oid_cs = (iod_checksum_t *)malloc(sizeof(iod_checksum_t) * (size_t)num_entries);
+ oid_ret = (iod_ret_t *)malloc(sizeof(iod_ret_t) * (size_t)num_entries);
+
+ for(i=0 ; i<num_entries ; i++) {
+ kv[i].key = malloc(sizeof(uint32_t));
+ kv[i].key_len = sizeof(uint32_t);
+ kv[i].value = malloc(val_size * 3);
+ kv[i].value_len = val_size * 3;
+ kvs[i].kv = &kv[i];
+ kvs[i].cs = &oid_cs[i];
+ kvs[i].ret = &oid_ret[i];
+ }
+
+ ret = iod_kv_get_list(oidkv_oh, rtid, NULL, 0, &num_entries, kvs, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't get KV list from OID KV");
+
+ for(i=0 ; i<num_entries ; i++) {
+ uint64_t *oid_index = (uint64_t *)kv[i].value;
+
+ if(output.kv_oid_index < oid_index[0])
+ output.kv_oid_index = oid_index[0];
+ if(output.array_oid_index < oid_index[1])
+ output.array_oid_index = oid_index[1];
+ if(output.blob_oid_index < oid_index[2])
+ output.blob_oid_index = oid_index[2];
+ }
+
+ for(i=0 ; i<num_entries ; i++) {
+ free(kv[i].key);
+ free(kv[i].value);
+ }
+
+ free(kv);
+ free(oid_cs);
+ free(oid_ret);
+ free(kvs);
+ }
+ /* This was a clean shutdown, so the maximum is already computed
+ and stored in the metadata KV */
+ else {
+ iod_checksum_t *iod_cs = NULL;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_cs = (iod_checksum_t *)malloc(sizeof(iod_checksum_t) * 2);
+ }
+
+ key_size = strlen(H5VL_IOD_KEY_KV_IDS_INDEX);
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_KV_IDS_INDEX, key_size,
+ &output.kv_oid_index, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "KV index lookup failed");
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_KV_IDS_INDEX, key_size,
+ &output.kv_oid_index, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ key_size = strlen(H5VL_IOD_KEY_ARRAY_IDS_INDEX);
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_ARRAY_IDS_INDEX, key_size,
+ &output.array_oid_index, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Array index lookup failed");
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_ARRAY_IDS_INDEX, key_size,
+ &output.array_oid_index, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ key_size = strlen(H5VL_IOD_KEY_BLOB_IDS_INDEX);
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_BLOB_IDS_INDEX, key_size,
+ &output.blob_oid_index, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "BLOB index lookup failed");
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_BLOB_IDS_INDEX, key_size,
+ &output.blob_oid_index, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ if(iod_cs) {
+ free(iod_cs);
+ iod_cs = NULL;
+ }
+ }
+
+ /* close the oid KV */
+ if(iod_obj_close(oidkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close OID KV");
+ /* close the metadata KV */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close MD KV");
+
+ output.coh.cookie = coh.cookie;
+ output.root_id = ROOT_ID;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+ output.oidkv_id = sp[2];
+ output.root_oh.rd_oh = root_oh.rd_oh;
+ output.root_oh.wr_oh = root_oh.wr_oh;
+ output.c_version = rtid;
+
+ /* If the user did not ask to acquire the latest readable version, finish it here */
+ if(TRUE != acquire) {
+ output.c_version = IOD_TID_UNKNOWN;
+ if(iod_trans_finish(coh, rtid, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't finish transaction 0");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with file open coh: %"PRIu64" root rd: %"PRIu64" wr: %"PRIu64" CV: %"PRIu64"\n",
+ coh.cookie, root_oh.rd_oh.cookie, root_oh.wr_oh.cookie, rtid);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.coh.cookie = IOD_OH_UNDEFINED;
+ output.root_id = IOD_OBJ_INVALID;
+ output.root_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.root_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.fcpl_id = H5P_FILE_CREATE_DEFAULT;
+ output.kv_oid_index = 0;
+ output.array_oid_index = 0;
+ output.blob_oid_index = 0;
+ output.c_version = IOD_TID_UNKNOWN;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (file_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_file_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_close_cb
+ *
+ * Purpose: Closes iod HDF5 file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_file_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ file_close_in_t *input = (file_close_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t root_oh = input->root_oh;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start file close\n");
+#endif
+
+ /* The root client request will create a transaction and store the
+ final indexes for used up IDs */
+ if(input->max_kv_index || input->max_array_index || input->max_blob_index) {
+ iod_cont_trans_stat_t *tids = NULL;
+ iod_trans_id_t trans_num, rtid;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_kv_t kv;
+ iod_handle_t mdkv_oh; /* metadata object handle for KV to store file's metadata */
+ uint32_t cs_scope = input->cs_scope;
+
+ if(iod_query_cont_trans_stat(coh, &tids, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get container tids status");
+
+ trans_num = tids->latest_wrting + 1;
+ rtid = tids->latest_rdable;
+
+ if(iod_free_cont_trans_stat(coh, tids) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free container transaction status object");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "File Close starting transaction %"PRIu64" rcxt %"PRIu64"\n",
+ trans_num, rtid);
+#endif
+
+ if((ret = iod_trans_start(coh, &rtid, NULL, 1, IOD_TRANS_R, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't start READ transaction");
+ }
+
+ if((ret = iod_trans_start(coh, &trans_num, NULL, 1, IOD_TRANS_W, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't start WRITE transaction");
+ }
+
+ /* get scratch pad of root group */
+ if((ret = iod_obj_get_scratch(root_oh.rd_oh, rtid, &sp, &sp_cs, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for root object");
+ }
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV object */
+ if (iod_obj_open_write(coh, sp[0], trans_num, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open metadata KV");
+
+ /* insert current indexes in the metadata KV object */
+ kv.value = &input->max_kv_index;
+ kv.value_len = sizeof(iod_obj_id_t);
+ kv.key = (void *)H5VL_IOD_KEY_KV_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_KV_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+
+ kv.value = &input->max_array_index;
+ kv.value_len = sizeof(iod_obj_id_t);
+ kv.key = (void *)H5VL_IOD_KEY_ARRAY_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_ARRAY_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+ kv.value = &input->max_blob_index;
+ kv.value_len = sizeof(iod_obj_id_t);
+ kv.key = (void *)H5VL_IOD_KEY_BLOB_IDS_INDEX;
+ kv.key_len = strlen(H5VL_IOD_KEY_BLOB_IDS_INDEX);
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(mdkv_oh, trans_num, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close root object handle");
+
+ /* open the OID kv object and remove all entries since this is
+ a clean shutdown and the summary is stored in the metadata
+ KV. */
+ {
+ iod_handles_t oidkv_oh;
+ int num_entries = 0, i;
+ iod_kv_params_t *kvs = NULL;
+ iod_kv_t *oid_kv = NULL;
+ iod_checksum_t *oid_cs = NULL;
+ iod_ret_t *oid_ret = NULL;
+
+ if (iod_obj_open_write(coh, sp[2], trans_num, NULL, &oidkv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open oid KV");
+ if (iod_obj_open_read(coh, sp[2], rtid, NULL, &oidkv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open oid KV");
+
+ ret = iod_kv_get_num(oidkv_oh.rd_oh, rtid, &num_entries, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't get number of KV entries");
+
+ fprintf(stderr, "NUM entries in OID index KV = %d\n", num_entries);
+
+ if(num_entries) {
+ kvs = (iod_kv_params_t *)malloc(sizeof(iod_kv_params_t) * (size_t)num_entries);
+ oid_kv = (iod_kv_t *)malloc(sizeof(iod_kv_t) * (size_t)num_entries);
+ oid_cs = (iod_checksum_t *)malloc(sizeof(iod_checksum_t) * (size_t)num_entries);
+ oid_ret = (iod_ret_t *)malloc(sizeof(iod_ret_t) * (size_t)num_entries);
+
+ for(i=0 ; i<num_entries ; i++) {
+ oid_kv[i].key = malloc(sizeof(uint32_t));
+ oid_kv[i].key_len = sizeof(uint32_t);
+ kvs[i].kv = &oid_kv[i];
+ kvs[i].cs = &oid_cs[i];
+ kvs[i].ret = &oid_ret[i];
+ }
+
+ ret = iod_kv_list_key(oidkv_oh.rd_oh, rtid, NULL, 0, &num_entries, kvs, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't get list of keys");
+
+ ret = iod_kv_unlink_keys(oidkv_oh.wr_oh, trans_num, NULL, num_entries, kvs, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't unlink keys in OID index KV");
+
+ for(i=0 ; i<num_entries ; i++)
+ free(oid_kv[i].key);
+ free(oid_kv);
+ free(oid_cs);
+ free(oid_ret);
+ free(kvs);
+ }
+
+ if(iod_obj_close(oidkv_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object handle");
+ if(iod_obj_close(oidkv_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object handle");
+ }
+
+ /* finish the transaction */
+ if(iod_trans_finish(coh, rtid, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't finish transaction");
+
+ /* finish the transaction */
+ if(iod_trans_finish(coh, trans_num, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't finish transaction");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Closing ROOT Group: R: %"PRIu64" W: %"PRIu64"\n",
+ root_oh.rd_oh.cookie, root_oh.wr_oh.cookie);
+#endif
+
+ /* close the root group */
+ if(iod_obj_close(root_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "can't close root object handle");
+ if(iod_obj_close(root_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "can't close root object handle");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Closing Container: %"PRIu64"\n", coh.cookie);
+#endif
+
+ /* close the container */
+ if((ret = iod_container_close(coh, NULL, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTDEC, FAIL, "can't close container");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with file close, sending response to client\n");
+#endif
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "can't send result of file close to client");
+
+ input = (file_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_file_close_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_group.c b/src/H5VLiod_group.c
new file mode 100644
index 0000000..0086bd0
--- /dev/null
+++ b/src/H5VLiod_group.c
@@ -0,0 +1,404 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side group routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_create_cb
+ *
+ * Purpose: Creates a group as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_group_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ group_create_in_t *input = (group_create_in_t *)op_data->input;
+ group_create_out_t output;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* The handle for current object - could be undefined */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t grp_id = input->grp_id; /* The ID of the group that needs to be created */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV to be created */
+ iod_obj_id_t attrkv_id = input->attrkv_id; /* The ID of the attirbute KV to be created */
+ const char *name = input->name; /* path relative to loc_id and loc_oh */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t grp_oh, cur_oh;
+ iod_handle_t mdkv_oh;
+ iod_obj_id_t cur_id;
+ char *last_comp = NULL; /* the name of the group obtained from traversal function */
+ iod_hint_list_t *obj_create_hint = NULL;
+ hbool_t enable_checksum = FALSE;
+ hid_t gcpl_id;
+ scratch_pad sp;
+ iod_ret_t ret;
+ int step = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start group create %s at %"PRIu64"\n", name, loc_handle.wr_oh.cookie);
+#endif
+
+ if(H5P_DEFAULT == input->gcpl_id)
+ input->gcpl_id = H5Pcopy(H5P_GROUP_CREATE_DEFAULT);
+ gcpl_id = input->gcpl_id;
+
+ /* get the scope for data integrity checks */
+ if(H5Pget_ocpl_enable_checksum(gcpl_id, &enable_checksum) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ /* the traversal will retrieve the location where the group needs
+ to be created. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, wtid, rtid, FALSE, cs_scope,
+ &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Creating Group ID %"PRIx64" (CV %"PRIu64", TR %"PRIu64") ",
+ grp_id, rtid, wtid);
+ fprintf(stderr, "at (OH %"PRIu64" ID %"PRIx64") ", cur_oh.wr_oh.cookie, cur_id);
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum)
+ fprintf(stderr, "with Data integrity ENABLED\n");
+ else
+ fprintf(stderr, "with Data integrity DISABLED\n");
+#endif
+
+ /* create the group */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &grp_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Group");
+
+ if((ret = iod_obj_open_read(coh, grp_id, wtid, NULL, &grp_oh.rd_oh, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Group for read");
+ }
+ if((ret = iod_obj_open_write(coh, grp_id, wtid, NULL, &grp_oh.wr_oh, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Group for write");
+ }
+
+ step += 1;
+
+ /* create the metadata KV object for the group */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &mdkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* create the attribute KV object for the group */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &attrkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = attrkv_id;
+ sp[2] = IOD_OBJ_INVALID;
+ sp[3] = IOD_OBJ_INVALID;
+
+ /* set scratch pad in group */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t sp_cs;
+
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+ if (iod_obj_set_scratch(grp_oh.wr_oh, wtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+ else {
+ if (iod_obj_set_scratch(grp_oh.wr_oh, wtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+
+ /* store metadata */
+ /* Open Metadata KV object for write */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create scratch pad");
+
+ step ++;
+
+ /* insert plist metadata */
+ if(H5VL_iod_insert_plist(mdkv_oh, wtid, gcpl_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh, wtid, (uint64_t)1,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert object type metadata */
+ if(H5VL_iod_insert_object_type(mdkv_oh, wtid, H5I_GROUP,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close Metadata KV object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ step --;
+
+ /* add link in parent group to current object */
+ if(H5VL_iod_insert_new_link(cur_oh.wr_oh, wtid, last_comp, H5L_TYPE_HARD,
+ &grp_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with group create, sending response to client\n");
+#endif
+
+ /* return the object handle for the group to the client */
+ output.iod_oh.rd_oh.cookie = grp_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = grp_oh.wr_oh.cookie;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+ fprintf(stderr, "Created group RD_OH %"PRIu64" WR_OH %"PRIu64"\n",
+ grp_oh.rd_oh.cookie, grp_oh.wr_oh.cookie);
+
+done:
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(loc_handle.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ /* return an UNDEFINED oh to the client if the operation failed */
+ if(ret_value < 0) {
+ fprintf(stderr, "Failed Group Create\n");
+
+ if(step == 2) {
+ iod_obj_close(mdkv_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ iod_obj_close(grp_oh.rd_oh, NULL, NULL);
+ iod_obj_close(grp_oh.wr_oh, NULL, NULL);
+ }
+
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ if(obj_create_hint) {
+ free(obj_create_hint);
+ obj_create_hint = NULL;
+ }
+
+ last_comp = (char *)H5MM_xfree(last_comp);
+ input = (group_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_group_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_open_cb
+ *
+ * Purpose: Opens a group as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_group_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ group_open_in_t *input = (group_open_in_t *)op_data->input;
+ group_open_out_t output;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_handle = input->loc_oh; /* location handle to start lookup */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ const char *name = input->name; /* group name including path to open */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_obj_id_t grp_id; /* The ID of the group that needs to be opened */
+ iod_handles_t grp_oh; /* The group handle */
+ iod_handle_t mdkv_oh; /* The metadata KV handle */
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start group open %s at (OH %"PRIu64" ID %"PRIx64")\n",
+ name, loc_handle.rd_oh.cookie, loc_id);
+#endif
+
+ /* if we are opening the root group, no need to traverse */
+ if(0 == strcmp(name, "/")) {
+ grp_id = ROOT_ID;
+ /* open a write handle on the ID. */
+ if(iod_obj_open_read(coh, grp_id, rtid, NULL, &grp_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ }
+ else {
+ /* Traverse Path and open group */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, name, rtid,
+ cs_scope, &grp_id, &grp_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+ }
+
+ /* open a write handle on the ID. */
+ if(iod_obj_open_write(coh, grp_id, rtid, NULL, &grp_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ /* get scratch pad of group */
+ if(iod_obj_get_scratch(grp_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.gcpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve gcpl");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close meta data KV handle");
+
+ output.iod_id = grp_id;
+ output.iod_oh.rd_oh.cookie = grp_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = grp_oh.wr_oh.cookie;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with group open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.gcpl_id = H5P_GROUP_CREATE_DEFAULT;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (group_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_group_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_close_cb
+ *
+ * Purpose: Closes iod HDF5 group.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_group_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ group_close_in_t *input = (group_close_in_t *)op_data->input;
+ iod_handles_t iod_oh = input->iod_oh;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start group close\n");
+#endif
+
+ if(IOD_OH_UNDEFINED == iod_oh.wr_oh.cookie ||
+ IOD_OH_UNDEFINED == iod_oh.rd_oh.cookie) {
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close object with invalid handle");
+ }
+
+ if((iod_obj_close(iod_oh.rd_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if((iod_obj_close(iod_oh.wr_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with group close, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (group_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_group_close_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_link.c b/src/H5VLiod_link.c
new file mode 100644
index 0000000..127861b
--- /dev/null
+++ b/src/H5VLiod_link.c
@@ -0,0 +1,866 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side link routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_create_cb
+ *
+ * Purpose: Creates a new link in the container (Hard or Soft).
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_create_in_t *input = (link_create_in_t *)op_data->input;
+ H5VL_link_create_type_t create_type = input->create_type;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t src_oh; /* The handle for creation src object */
+ iod_obj_id_t src_id; /* The ID of the creation src object */
+ iod_handles_t target_oh;
+ iod_obj_id_t target_id; /* The ID of the target object where link is created*/
+ char *src_last_comp = NULL, *dst_last_comp = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Link create\n");
+#endif
+
+ /* the traversal will retrieve the location where the link needs
+ to be created from. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, input->loc_id, input->loc_oh, input->loc_name,
+ wtid, rtid, FALSE, cs_scope, &src_last_comp, &src_id, &src_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "new link name = %s\n", src_last_comp);
+#endif
+
+ if(H5VL_LINK_CREATE_HARD == create_type) {
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_handles_t mdkv_oh;
+ uint64_t link_count = 0;
+ hbool_t opened_locally = FALSE;
+
+ if(input->target_loc_oh.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ /* Try and open the starting location */
+ if (iod_obj_open_read(coh, input->target_loc_id, wtid, NULL,
+ &input->target_loc_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open start location");
+ opened_locally = TRUE;
+ }
+ /* Traverse Path and open the target object */
+ if(H5VL_iod_server_open_path(coh, input->target_loc_id, input->target_loc_oh,
+ input->target_name, rtid, cs_scope, &target_id, &target_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* add link in parent group to current object */
+ if(H5VL_iod_insert_new_link(src_oh.wr_oh, wtid, src_last_comp,
+ H5L_TYPE_HARD, &target_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ if(input->target_loc_id != target_id) {
+ /* get scratch pad */
+ if(iod_obj_get_scratch(target_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+ else {
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, input->target_mdkv_id, rtid, NULL, &mdkv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, input->target_mdkv_id, rtid, NULL, &mdkv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ }
+
+ if(H5VL_iod_get_metadata(mdkv_oh.rd_oh, rtid, H5VL_IOD_LINK_COUNT,
+ H5VL_IOD_KEY_OBJ_LINK_COUNT,
+ cs_scope, NULL, &link_count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ link_count ++;
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh.wr_oh, wtid, link_count,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if(iod_obj_close(mdkv_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* close the target location */
+ if(TRUE == opened_locally ||
+ input->target_loc_oh.rd_oh.cookie != target_oh.rd_oh.cookie) {
+ if(iod_obj_close(target_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+ }
+ else if(H5VL_LINK_CREATE_SOFT == create_type) {
+ /* add link in parent group to the source location */
+ if(H5VL_iod_insert_new_link(src_oh.wr_oh, wtid, src_last_comp,
+ H5L_TYPE_SOFT, input->link_value,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Soft link Value = %s\n", input->link_value);
+#endif
+ }
+ else
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Invalid Link type");
+
+ /* close the source location */
+ if(input->loc_oh.rd_oh.cookie != src_oh.rd_oh.cookie) {
+ if(iod_obj_close(src_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+ if(input->loc_oh.wr_oh.cookie != src_oh.wr_oh.cookie) {
+ if(iod_obj_close(src_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with link create, sending response %d to client\n",
+ ret_value);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ src_last_comp = (char *)H5MM_xfree(src_last_comp);
+ dst_last_comp = (char *)H5MM_xfree(dst_last_comp);
+ input = (link_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_move_cb
+ *
+ * Purpose: Moves/Copies a link in the container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_move_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_move_in_t *input = (link_move_in_t *)op_data->input;
+ hbool_t copy_flag = input->copy_flag;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t src_oh; /* The handle for src object group */
+ iod_obj_id_t src_id; /* The ID of the src object */
+ iod_handles_t dst_oh; /* The handle for the dst object where link is created*/
+ iod_obj_id_t dst_id; /* The ID of the dst object where link is created*/
+ char *src_last_comp = NULL, *dst_last_comp = NULL;
+ iod_kv_t kv;
+ H5VL_iod_link_t iod_link;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start link move SRC %s DST %s (%"PRIu64", %"PRIu64") to (%"PRIu64", %"PRIu64")\n",
+ input->src_loc_name, input->dst_loc_name,
+ input->src_loc_oh.wr_oh.cookie, input->src_loc_oh.rd_oh.cookie,
+ input->dst_loc_oh.wr_oh.cookie, input->dst_loc_oh.rd_oh.cookie);
+#endif
+
+ /* the traversal will retrieve the location where the link needs
+ to be moved/copied from. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, input->src_loc_id, input->src_loc_oh,
+ input->src_loc_name, wtid, rtid, FALSE, cs_scope,
+ &src_last_comp, &src_id, &src_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+ /* the traversal will retrieve the location where the link needs
+ to be moved/copied to. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, input->dst_loc_id, input->dst_loc_oh,
+ input->dst_loc_name, wtid, rtid, FALSE, cs_scope,
+ &dst_last_comp, &dst_id, &dst_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+ /* get the link value */
+ if(H5VL_iod_get_metadata(src_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ src_last_comp, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+
+ /* Insert object in the destination path */
+ if(H5L_TYPE_HARD == iod_link.link_type) {
+ if(H5VL_iod_insert_new_link(dst_oh.wr_oh, wtid, dst_last_comp,
+ iod_link.link_type, &iod_link.u.iod_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+ }
+ else if(H5L_TYPE_SOFT == iod_link.link_type) {
+ if(H5VL_iod_insert_new_link(dst_oh.wr_oh, wtid, dst_last_comp,
+ iod_link.link_type, &iod_link.u.symbolic_name,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+ }
+
+ /* if the operation type is a Move, remove the KV pair from the source object */
+ if(!copy_flag) {
+ iod_kv_params_t kvs;
+ iod_ret_t ret;
+ iod_checksum_t cs;
+
+ kv.key = src_last_comp;
+ kv.key_len = strlen(src_last_comp);
+ kvs.kv = &kv;
+ kvs.cs = &cs;
+ kvs.ret = &ret;
+
+ /* remove link from source object */
+ if(iod_kv_unlink_keys(src_oh.wr_oh, wtid, NULL, 1, &kvs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+ }
+
+ /* adjust link count on target object */
+ {
+ iod_handle_t target_oh;
+ iod_handles_t mdkv_oh;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ uint64_t link_count = 0;
+
+ /* open the current group */
+ if (iod_obj_open_read(coh, iod_link.u.iod_id, rtid, NULL, &target_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ /* get scratch pad */
+ if(iod_obj_get_scratch(target_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh.rd_oh, rtid, H5VL_IOD_LINK_COUNT,
+ H5VL_IOD_KEY_OBJ_LINK_COUNT,
+ cs_scope, NULL, &link_count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ link_count ++;
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh.wr_oh, wtid, link_count,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if(iod_obj_close(mdkv_oh.wr_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* close the target location */
+ if(iod_obj_close(target_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ }
+
+ /* close source group if it is not the location we started the
+ traversal into */
+ if(input->src_loc_oh.rd_oh.cookie != src_oh.rd_oh.cookie) {
+ iod_obj_close(src_oh.rd_oh, NULL, NULL);
+ }
+ if(input->src_loc_oh.wr_oh.cookie != src_oh.wr_oh.cookie) {
+ iod_obj_close(src_oh.wr_oh, NULL, NULL);
+ }
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(input->dst_loc_oh.rd_oh.cookie != dst_oh.rd_oh.cookie) {
+ iod_obj_close(dst_oh.rd_oh, NULL, NULL);
+ }
+ if(input->dst_loc_oh.wr_oh.cookie != dst_oh.wr_oh.cookie) {
+ iod_obj_close(dst_oh.wr_oh, NULL, NULL);
+ }
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with link move, sending response %d to client\n",
+ ret_value);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ src_last_comp = (char *)H5MM_xfree(src_last_comp);
+ dst_last_comp = (char *)H5MM_xfree(dst_last_comp);
+ input = (link_move_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ if(iod_link.link_type == H5L_TYPE_SOFT) {
+ if(iod_link.u.symbolic_name)
+ free(iod_link.u.symbolic_name);
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_move_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_exists_cb
+ *
+ * Purpose: Checks if a link exists.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_exists_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_op_in_t *input = (link_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_handles_t cur_oh;
+ iod_obj_id_t cur_id;
+ const char *loc_name = input->path;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ char *last_comp = NULL;
+ htri_t ret = -1;
+ iod_size_t val_size = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start link Exists for %s on CV %d\n", loc_name, (int)rtid);
+#endif
+
+ /* the traversal will retrieve the location where the link needs
+ to be checked */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_oh, loc_name, rtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0) {
+ ret = FALSE;
+ HGOTO_DONE(SUCCEED);
+ }
+
+ /* check the last component */
+ if(iod_kv_get_value(cur_oh.rd_oh, rtid, last_comp, (iod_size_t)strlen(last_comp),
+ NULL, &val_size, NULL, NULL) < 0) {
+ ret = FALSE;
+ } /* end if */
+ else {
+ H5VL_iod_link_t iod_link;
+
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ last_comp, cs_scope, NULL, &iod_link) < 0) {
+ ret = FALSE;
+ }
+ else {
+ iod_handle_t rd_oh;
+
+ if (iod_obj_open_read(coh, iod_link.u.iod_id, rtid, NULL, &rd_oh, NULL) < 0) {
+ ret = FALSE;
+ }
+ else {
+ if(iod_obj_close(rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close current object handle");
+ ret = TRUE;
+ }
+ }
+ }
+
+done:
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(input->loc_oh.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(input->loc_oh.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with link exists, sending %d to client\n", ret);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret);
+
+ input = (link_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+ last_comp = (char *)H5MM_xfree(last_comp);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_exists_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_get_info_cb
+ *
+ * Purpose: Checks if a link get_info.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_get_info_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_op_in_t *input = (link_op_in_t *)op_data->input;
+ H5L_ff_info_t linfo;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_handles_t cur_oh;
+ iod_obj_id_t cur_id;
+ const char *loc_name = input->path;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ char *last_comp = NULL;
+ H5VL_iod_link_t iod_link;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* the traversal will retrieve the location where the link needs
+ to be checked */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_oh, loc_name, rtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Link Get_Info on link %s\n", last_comp);
+#endif
+
+ /* lookup link information in the current location */
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ last_comp, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+
+ /* setup link info */
+ linfo.type = iod_link.link_type;
+ linfo.cset = 0;
+ switch (linfo.type) {
+ case H5L_TYPE_HARD:
+ linfo.u.address = iod_link.u.iod_id;
+ break;
+ case H5L_TYPE_SOFT:
+ linfo.u.val_size = strlen(iod_link.u.symbolic_name) + 1;
+ break;
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_EXTERNAL:
+ case H5L_TYPE_MAX:
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "unsuppored link type");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with link get_info, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &linfo);
+
+done:
+
+ if(ret_value < 0) {
+ fprintf(stderr, "FAILED link get_info, sending ERROR to client\n");
+ linfo.type = H5L_TYPE_ERROR;
+ HG_Handler_start_output(op_data->hg_handle, &linfo);
+ }
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(input->loc_oh.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(input->loc_oh.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ input = (link_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+ last_comp = (char *)H5MM_xfree(last_comp);
+
+ if(iod_link.link_type == H5L_TYPE_SOFT) {
+ if(iod_link.u.symbolic_name)
+ free(iod_link.u.symbolic_name);
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_get_info_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_get_val_cb
+ *
+ * Purpose: Get comment for an object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_get_val_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_get_val_in_t *input = (link_get_val_in_t *)op_data->input;
+ link_get_val_out_t output;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ size_t length = input->length;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t cur_oh;
+ iod_obj_id_t cur_id;
+ const char *loc_name = input->path;
+ char *last_comp = NULL;
+ H5VL_iod_link_t iod_link;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* the traversal will retrieve the location where the link needs
+ to be checked */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_oh, loc_name, rtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Link Get_val on link %s\n", last_comp);
+#endif
+
+ /* lookup link information in the current location */
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ last_comp, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+
+ if(H5L_TYPE_SOFT != iod_link.link_type)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "link is not SOFT");
+
+ output.value.val_size = length;
+ output.value.val = NULL;
+
+ if(length) {
+ if(NULL == (output.value.val = (void *)malloc (length)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+ memcpy(output.value.val, iod_link.u.symbolic_name, length);
+ }
+
+ output.ret = ret_value;
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with get link_val, sending (%s) response to client\n",
+ (char *)output.value.val);
+#endif
+ if(ret_value < 0) {
+ output.ret = ret_value;
+ output.value.val = NULL;
+ output.value.val_size = 0;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(input->loc_oh.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(input->loc_oh.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ input = (link_get_val_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+ last_comp = (char *)H5MM_xfree(last_comp);
+
+ if(output.value.val)
+ free(output.value.val);
+
+ if(iod_link.link_type == H5L_TYPE_SOFT) {
+ if(iod_link.u.symbolic_name)
+ free(iod_link.u.symbolic_name);
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_get_val_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_remove_cb
+ *
+ * Purpose: Removes a link from a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_link_remove_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ link_op_in_t *input = (link_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t cur_oh;
+ iod_obj_id_t cur_id;
+ iod_handle_t obj_oh;
+ iod_handles_t mdkv_oh;
+ const char *loc_name = input->path;
+ char *last_comp = NULL;
+ iod_kv_params_t kvs;
+ iod_kv_t kv;
+ iod_ret_t ret;
+ iod_checksum_t cs;
+ H5VL_iod_link_t iod_link;
+ int step = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start link Remove %s at (%"PRIu64", %"PRIu64")\n",
+ loc_name, loc_oh.wr_oh.cookie, loc_oh.rd_oh.cookie);
+#endif
+
+ /* the traversal will retrieve the location where the link needs
+ to be removed. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_oh, loc_name, wtid, rtid,
+ FALSE, cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+ /* lookup object ID in the current location */
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ last_comp, cs_scope, NULL, &iod_link) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+
+ /* unlink object from conainer */
+ kv.key = last_comp;
+ kv.key_len = strlen(last_comp);
+ kvs.kv = &kv;
+ kvs.cs = &cs;
+ kvs.ret = &ret;
+ if(iod_kv_unlink_keys(cur_oh.wr_oh, wtid, NULL, 1, &kvs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+
+ /* check the metadata information for the object and remove
+ it from the container if this is the last link to it */
+ if(iod_link.link_type == H5L_TYPE_HARD) {
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ uint64_t link_count = 0;
+ iod_obj_id_t obj_id;
+
+ obj_id = iod_link.u.iod_id;
+
+ /* open the current group */
+ if (iod_obj_open_read(coh, obj_id, rtid, NULL, &obj_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ step ++;
+
+ /* get scratch pad */
+ if(iod_obj_get_scratch(obj_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+ if (iod_obj_open_write(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ step ++;
+
+ if(H5VL_iod_get_metadata(mdkv_oh.rd_oh, rtid, H5VL_IOD_LINK_COUNT,
+ H5VL_IOD_KEY_OBJ_LINK_COUNT,
+ cs_scope, NULL, &link_count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ link_count --;
+
+ /* if this is not the only link to the object, update the link count */
+ if(0 != link_count) {
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh.wr_oh, wtid, link_count,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+ }
+
+ iod_obj_close(mdkv_oh.rd_oh, NULL, NULL);
+ iod_obj_close(mdkv_oh.wr_oh, NULL, NULL);
+
+ step --;
+
+ iod_obj_close(obj_oh, NULL, NULL);
+
+ step --;
+
+ /* If this was the only link to the object, remove the object */
+ if(0 == link_count) {
+ if(iod_obj_unlink(coh, obj_id, wtid, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink object");
+ if(iod_obj_unlink(coh, sp[0], wtid, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink MDKV object");
+ if(iod_obj_unlink(coh, sp[1], wtid, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink ATTRKV object");
+ }
+ }
+
+done:
+
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(input->loc_oh.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(input->loc_oh.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ if(step == 2) {
+ /* close the metadata scratch pad */
+ iod_obj_close(mdkv_oh.rd_oh, NULL, NULL);
+ iod_obj_close(mdkv_oh.wr_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ iod_obj_close(obj_oh, NULL, NULL);
+ step --;
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with link remove, sending response %d to client\n",
+ ret_value);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ last_comp = (char *)H5MM_xfree(last_comp);
+ input = (link_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ if(iod_link.link_type == H5L_TYPE_SOFT) {
+ if(iod_link.u.symbolic_name)
+ free(iod_link.u.symbolic_name);
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_link_remove_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_map.c b/src/H5VLiod_map.c
new file mode 100644
index 0000000..7e3aa0b
--- /dev/null
+++ b/src/H5VLiod_map.c
@@ -0,0 +1,1079 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * July, 2013
+ *
+ * Purpose: The IOD plugin server side map routines.
+ */
+
+/* temp debug value for faking vl data */
+int g_debug_counter = 0;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_create_cb
+ *
+ * Purpose: Creates a map as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_create_in_t *input = (map_create_in_t *)op_data->input;
+ map_create_out_t output;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_handles_t loc_handle = input->loc_oh; /* The handle for current object - could be undefined */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */
+ iod_obj_id_t map_id = input->map_id; /* The ID of the map that needs to be created */
+ iod_obj_id_t mdkv_id = input->mdkv_id; /* The ID of the metadata KV to be created */
+ iod_obj_id_t attr_id = input->attrkv_id; /* The ID of the attirbute KV to be created */
+ const char *name = input->name; /* path relative to loc_id and loc_oh */
+ hid_t keytype = input->keytype_id;
+ hid_t valtype = input->valtype_id;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t map_oh, cur_oh;
+ iod_handle_t mdkv_oh;
+ iod_obj_id_t cur_id;
+ char *last_comp; /* the name of the group obtained from traversal function */
+ hid_t mcpl_id;
+ iod_hint_list_t *obj_create_hint = NULL;
+ hbool_t enable_checksum = FALSE;
+ int step = 0;
+ scratch_pad sp;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map create %s at %"PRIu64"\n",
+ name, loc_handle.wr_oh.cookie);
+#endif
+
+ if(H5P_DEFAULT == input->mcpl_id)
+ input->mcpl_id = H5Pcopy(H5P_MAP_CREATE_DEFAULT);
+ mcpl_id = input->mcpl_id;
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_ocpl_enable_checksum(mcpl_id, &enable_checksum) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum) {
+ obj_create_hint = (iod_hint_list_t *)malloc(sizeof(iod_hint_list_t) + sizeof(iod_hint_t));
+ obj_create_hint->num_hint = 1;
+ obj_create_hint->hint[0].key = "iod_hint_obj_enable_cksum";
+ }
+
+ /* the traversal will retrieve the location where the map needs
+ to be created. The traversal will fail if an intermediate group
+ does not exist. */
+ if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, wtid, rtid, FALSE,
+ cs_scope, &last_comp, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Creating Map ID %"PRIx64") ", map_id);
+ fprintf(stderr, "at (OH %"PRIu64" ID %"PRIx64") ", cur_oh.wr_oh.cookie, cur_id);
+ if((cs_scope & H5_CHECKSUM_IOD) && enable_checksum)
+ fprintf(stderr, "with Data integrity ENABLED\n");
+ else
+ fprintf(stderr, "with Data integrity DISABLED\n");
+#endif
+
+ /* create the map */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &map_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Map");
+
+ if (iod_obj_open_read(coh, map_id, wtid, NULL, &map_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Map");
+ if (iod_obj_open_write(coh, map_id, wtid, NULL, &map_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Map");
+
+ step ++;
+
+ /* create the metadata KV object for the map */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &mdkv_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* create the attribute KV object for the root group */
+ if(iod_obj_create(coh, wtid, obj_create_hint, IOD_OBJ_KV,
+ NULL, NULL, &attr_id, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object");
+
+ /* set values for the scratch pad object */
+ sp[0] = mdkv_id;
+ sp[1] = attr_id;
+ sp[2] = IOD_OBJ_INVALID;
+ sp[3] = IOD_OBJ_INVALID;
+
+ /* set scratch pad in map */
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t sp_cs;
+
+ sp_cs = H5_checksum_crc64(&sp, sizeof(sp));
+ if (iod_obj_set_scratch(map_oh.wr_oh, wtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+ else {
+ if (iod_obj_set_scratch(map_oh.wr_oh, wtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad");
+ }
+
+ /* Open Metadata KV object for write */
+ if (iod_obj_open_write(coh, mdkv_id, wtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't create scratch pad");
+
+ step ++;
+
+ /* insert plist metadata */
+ if(H5VL_iod_insert_plist(mdkv_oh, wtid, mcpl_id,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert link count metadata */
+ if(H5VL_iod_insert_link_count(mdkv_oh, wtid, (uint64_t)1,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert object type metadata */
+ if(H5VL_iod_insert_object_type(mdkv_oh, wtid, H5I_MAP,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert Key datatype metadata */
+ if(H5VL_iod_insert_datatype_with_key(mdkv_oh, wtid, keytype, H5VL_IOD_KEY_MAP_KEY_TYPE,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* insert Value datatype metadata */
+ if(H5VL_iod_insert_datatype_with_key(mdkv_oh, wtid, valtype, H5VL_IOD_KEY_MAP_VALUE_TYPE,
+ cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close MD KV object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ step --;
+
+ /* add link in parent group to current object */
+ if(H5VL_iod_insert_new_link(cur_oh.wr_oh, wtid, last_comp,
+ H5L_TYPE_HARD, &map_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map create, sending response to client\n");
+#endif
+
+ /* return the object handle for the map to the client */
+ output.iod_oh.rd_oh.cookie = map_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = map_oh.wr_oh.cookie;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ /* close parent group if it is not the location we started the
+ traversal into */
+ if(loc_handle.rd_oh.cookie != cur_oh.rd_oh.cookie) {
+ iod_obj_close(cur_oh.rd_oh, NULL, NULL);
+ }
+ if(loc_handle.wr_oh.cookie != cur_oh.wr_oh.cookie) {
+ iod_obj_close(cur_oh.wr_oh, NULL, NULL);
+ }
+
+ /* return an UNDEFINED oh to the client if the operation failed */
+ if(ret_value < 0) {
+ fprintf(stderr, "Failed Map Create\n");
+
+ if(step == 2) {
+ iod_obj_close(mdkv_oh, NULL, NULL);
+ step --;
+ }
+ if(step == 1) {
+ iod_obj_close(map_oh.rd_oh, NULL, NULL);
+ iod_obj_close(map_oh.wr_oh, NULL, NULL);
+ }
+
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ if(obj_create_hint) {
+ free(obj_create_hint);
+ obj_create_hint = NULL;
+ }
+
+ last_comp = (char *)H5MM_xfree(last_comp);
+ input = (map_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_open_cb
+ *
+ * Purpose: Opens a map as a iod object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_open_in_t *input = (map_open_in_t *)op_data->input;
+ map_open_out_t output;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_handle = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ const char *name = input->name;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_obj_id_t map_id; /* The ID of the map that needs to be opened */
+ iod_handles_t map_oh;
+ iod_handle_t mdkv_oh;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map open %s at (OH %"PRIu64" ID %"PRIx64")\n",
+ name, loc_handle.rd_oh.cookie, loc_id);
+#endif
+
+ output.keytype_id = -1;
+ output.valtype_id = -1;
+
+ /* Traverse Path and open map */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_handle, name, rtid,
+ cs_scope, &map_id, &map_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* open a write handle on the ID. */
+ if (iod_obj_open_write(coh, map_id, rtid, NULL, &map_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current map");
+
+ /* get scratch pad of map */
+ if(iod_obj_get_scratch(map_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST,
+ H5VL_IOD_KEY_OBJ_CPL, cs_scope, NULL, &output.mcpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve gcpl");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_MAP_KEY_TYPE,
+ cs_scope, NULL, &output.keytype_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_MAP_VALUE_TYPE,
+ cs_scope, NULL, &output.valtype_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close meta data KV handle");
+
+ output.iod_id = map_id;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+ output.iod_oh.rd_oh.cookie = map_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = map_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.keytype_id = FAIL;
+ output.valtype_id = FAIL;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (map_open_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_set_cb
+ *
+ * Purpose: Insert/Set a KV pair in map object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_set_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_set_in_t *input = (map_set_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handle_t iod_oh = input->iod_oh.wr_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ hid_t key_memtype_id = input->key_memtype_id;
+ hid_t val_memtype_id = input->val_memtype_id;
+ hid_t key_maptype_id = input->key_maptype_id;
+ hid_t val_maptype_id = input->val_maptype_id;
+ binary_buf_t key = input->key;
+ hg_bulk_t value_handle = input->val_handle; /* bulk handle for data */
+ iod_checksum_t value_cs = input->val_checksum; /* checksum recieved for data */
+ hid_t dxpl_id = input->dxpl_id;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); /* source address to pull data from */
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ size_t key_size, val_size, new_val_size;
+ void *val_buf = NULL;
+ iod_kv_t kv;
+ uint32_t raw_cs_scope;
+ hbool_t opened_locally = FALSE;
+ hbool_t val_is_vl_data = FALSE, key_is_vl_data = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Map Set Key %d on OH %"PRIu64" OID %"PRIx64"\n",
+ *((int *)key.buf), iod_oh.cookie, iod_id);
+#endif
+
+ /* open the map if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, wtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ if(H5P_DEFAULT == input->dxpl_id)
+ input->dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT);
+ dxpl_id = input->dxpl_id;
+
+ /* retrieve size of incoming bulk data */
+ val_size = HG_Bulk_handle_get_size(value_handle);
+
+ /* allocate buffer to hold data */
+ if(NULL == (val_buf = malloc(val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* create a Mercury block handle for transfer */
+ HG_Bulk_handle_create(val_buf, val_size, HG_BULK_READWRITE, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_read_all(source, value_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper");
+
+ /* free the bds block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle");
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_rawdata_integrity_scope(dxpl_id, &raw_cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* verify data if transfer flag is set */
+ if(raw_cs_scope & H5_CHECKSUM_TRANSFER) {
+ iod_checksum_t data_cs;
+
+ data_cs = H5_checksum_crc64(val_buf, val_size);
+ if(value_cs != data_cs) {
+ fprintf(stderr, "Errrr.. Network transfer Data corruption. expecting %"PRIu64", got %"PRIu64"\n",
+ value_cs, data_cs);
+ ret_value = FAIL;
+ goto done;
+ }
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+
+ /* adjust buffers for datatype conversion */
+ if(H5VL__iod_server_adjust_buffer(key_memtype_id, key_maptype_id, 1, dxpl_id,
+ key.buf_size, &key.buf, &key_is_vl_data, &key_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ if(H5VL__iod_server_adjust_buffer(val_memtype_id, val_maptype_id, 1, dxpl_id,
+ val_size, &val_buf, &val_is_vl_data, &new_val_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+#if H5VL_IOD_DEBUG
+ /* fake debugging */
+ if(val_is_vl_data) {
+ H5T_class_t dt_class;
+ size_t seq_len = val_size, u;
+ uint8_t *buf_ptr = (uint8_t *)val_buf;
+
+ dt_class = H5Tget_class(val_memtype_id);
+
+ if(H5T_STRING == dt_class)
+ fprintf(stderr, "String Length %zu: %s\n", seq_len, (char *)buf_ptr);
+ else if(H5T_VLEN == dt_class) {
+ int *ptr = (int *)buf_ptr;
+
+ fprintf(stderr, "Sequence Count %zu: ", seq_len);
+ for(u=0 ; u<seq_len/sizeof(int) ; ++u)
+ fprintf(stderr, "%d ", ptr[u]);
+ fprintf(stderr, "\n");
+ }
+ }
+ else {
+ fprintf(stderr, "Map Set value = %d; size = %zu\n", *((int *)val_buf), val_size);
+ }
+#endif
+
+ if(!key_is_vl_data) {
+ /* convert data if needed */
+ if(H5Tconvert(key_memtype_id, key_maptype_id, 1, key.buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+ }
+ if(!val_is_vl_data) {
+ if(H5Tconvert(val_memtype_id, val_maptype_id, 1, val_buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+ }
+
+ /* MSC - do IOD checksum - can't now */
+
+ kv.key = key.buf;
+ kv.key_len = key_size;
+ kv.value = val_buf;
+ kv.value_len = (iod_size_t)new_val_size;
+
+ /* insert kv pair into MAP */
+ if(raw_cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ if (iod_kv_set(iod_oh, wtid, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in Map");
+ }
+ else {
+ if (iod_kv_set(iod_oh, wtid, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in Map");
+ }
+
+done:
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't send result of write to client");
+
+ input = (map_set_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ if(val_buf)
+ free(val_buf);
+
+ /* close the map if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map set, sent %d response to client\n", ret_value);
+#endif
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_set_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_get_cb
+ *
+ * Purpose: Get a KV pair in map object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_get_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_get_in_t *input = (map_get_in_t *)op_data->input;
+ map_get_out_t output;
+ iod_handle_t coh = input->coh;
+ iod_handle_t iod_oh = input->iod_oh.rd_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ hid_t key_memtype_id = input->key_memtype_id;
+ hid_t val_memtype_id = input->val_memtype_id;
+ hid_t key_maptype_id = input->key_maptype_id;
+ hid_t val_maptype_id = input->val_maptype_id;
+ binary_buf_t key = input->key;
+ hid_t dxpl_id = input->dxpl_id;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ hbool_t val_is_vl = input->val_is_vl;
+ size_t client_val_buf_size = input->val_size;
+ hg_bulk_t value_handle = input->val_handle; /* bulk handle for data */
+ uint32_t raw_cs_scope;
+ hbool_t key_is_vl = FALSE;
+ size_t key_size, val_size;
+ iod_size_t src_size;
+ void *val_buf = NULL;
+ hg_bulk_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */
+ hbool_t opened_locally = FALSE;
+ iod_checksum_t kv_cs[2];
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Map Get Key %d on OH %"PRIu64" OID %"PRIx64"\n",
+ *((int *)key.buf), iod_oh.cookie, iod_id);
+#endif
+
+ /* open the map if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, iod_id, rtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ if(H5P_DEFAULT == input->dxpl_id)
+ input->dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT);
+ dxpl_id = input->dxpl_id;
+
+ /* get the scope for data integrity checks for raw data */
+ if(H5Pget_rawdata_integrity_scope(dxpl_id, &raw_cs_scope) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get scope for data integrity checks");
+
+ /* adjust buffers for datatype conversion */
+ if(H5VL__iod_server_adjust_buffer(key_memtype_id, key_maptype_id, 1, dxpl_id,
+ key.buf_size, &key.buf, &key_is_vl, &key_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ if(iod_kv_get_value(iod_oh, rtid, key.buf, (iod_size_t)key.buf_size, NULL,
+ &src_size, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve value from parent KV store");
+
+ if(val_is_vl) {
+ output.ret = ret_value;
+ output.val_size = src_size;
+ fprintf(stderr, "val size = %zu\n", src_size);
+ if(client_val_buf_size) {
+ if(NULL == (val_buf = malloc((size_t)src_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer");
+
+ if(iod_kv_get_value(iod_oh, rtid, key.buf, (iod_size_t)key.buf_size, val_buf,
+ &src_size, kv_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve value from parent KV store");
+
+ if(raw_cs_scope) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(key.buf, key.buf_size);
+ cs[1] = H5_checksum_crc64(val_buf, src_size);
+
+ if(kv_cs[0] != cs[0] && kv_cs[1] != cs[1])
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected in IOD KV pair");
+
+ /* set checksum for the data to be sent */
+ output.val_cs = kv_cs[1];
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_handle_create(val_buf, (size_t)src_size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, value_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* free block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't free bds block handle");
+ }
+ }
+ else {
+ /* retrieve size of bulk data asked for to be read */
+ src_size = HG_Bulk_handle_get_size(value_handle);
+
+ if(NULL == (val_buf = malloc((size_t)src_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer");
+
+ if(iod_kv_get_value(iod_oh, rtid, key.buf, (iod_size_t)key.buf_size, val_buf,
+ &src_size, kv_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve value from parent KV store");
+
+ if(raw_cs_scope) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(key.buf, key.buf_size);
+ cs[1] = H5_checksum_crc64(val_buf, src_size);
+
+ if(kv_cs[0] != cs[0] && kv_cs[1] != cs[1])
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected in IOD KV pair");
+
+ /* set checksum for the data to be sent */
+ output.val_cs = kv_cs[1];
+ }
+
+ /* adjust buffers for datatype conversion */
+ if(H5VL__iod_server_adjust_buffer(val_memtype_id, val_maptype_id, 1, dxpl_id,
+ (size_t)src_size, &val_buf, &val_is_vl, &val_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /* do data conversion */
+ if(H5Tconvert(val_maptype_id, val_memtype_id, 1, val_buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ if(raw_cs_scope) {
+ /* calculate a checksum for the data to be sent */
+ output.val_cs = H5_checksum_crc64(val_buf, val_size);
+ }
+#if H5VL_IOD_DEBUG
+ else {
+ fprintf(stderr, "NO TRANSFER DATA INTEGRITY CHECKS ON RAW DATA\n");
+ }
+#endif
+
+ output.val_size = val_size;
+ output.ret = ret_value;
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_handle_create(val_buf, val_size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, value_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* free block handle */
+ if(HG_SUCCESS != HG_Bulk_handle_free(bulk_block_handle))
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "can't free bds block handle");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map get, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get");
+
+done:
+
+ if(ret_value < 0) {
+ output.ret = FAIL;
+ output.val_size = 0;
+ output.val_cs = 0;
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get");
+ }
+
+ if(val_buf)
+ free(val_buf);
+
+ input = (map_get_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the map if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_get_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_get_count_cb
+ *
+ * Purpose: Get number of KV pairs in map object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_get_count_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_get_count_in_t *input = (map_get_count_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handle_t iod_oh = input->iod_oh.rd_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ int num;
+ hsize_t output;
+ hbool_t opened_locally = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map get_count \n");
+#endif
+
+ /* open the map if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, iod_id, rtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ if(iod_kv_get_num(iod_oh, rtid, &num, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Number of KV pairs in MAP");
+
+ output = (hsize_t)num;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map get_count, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get");
+
+done:
+
+ if(ret_value < 0) {
+ output = IOD_COUNT_UNDEFINED;
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &output))
+ HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get_count");
+ }
+
+ input = (map_get_count_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the map if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_get_count_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_exists_cb
+ *
+ * Purpose: check if a key Exists in map object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_exists_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_op_in_t *input = (map_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handle_t iod_oh = input->iod_oh.wr_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ hid_t key_memtype_id = input->key_memtype_id;
+ hid_t key_maptype_id = input->key_maptype_id;
+ binary_buf_t key = input->key;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ size_t key_size;
+ iod_size_t val_size = 0;
+ hbool_t opened_locally = FALSE;
+ htri_t exists;
+ hbool_t is_vl_data = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map exists \n");
+#endif
+
+ /* open the map if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, iod_id, rtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ /* adjust buffers for datatype conversion */
+ if(H5VL__iod_server_adjust_buffer(key_memtype_id, key_maptype_id, 1, H5P_DEFAULT,
+ key.buf_size, &key.buf, &is_vl_data, &key_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /* determine if the Key exists by querying its value size */
+ if(iod_kv_get_value(iod_oh, rtid, key.buf, (iod_size_t)key.buf_size, NULL,
+ &val_size, NULL, NULL) < 0)
+ exists = FALSE;
+ else
+ exists = TRUE;
+
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map exists, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &exists))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get");
+
+done:
+
+ if(ret_value < 0) {
+ exists = -1;
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &exists))
+ HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map exists");
+ }
+
+ input = (map_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the map if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_exists_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_delete_cb
+ *
+ * Purpose: Delete a KV pair in map object
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_delete_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_op_in_t *input = (map_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handle_t iod_oh = input->iod_oh.wr_oh;
+ iod_obj_id_t iod_id = input->iod_id;
+ hid_t key_memtype_id = input->key_memtype_id;
+ hid_t key_maptype_id = input->key_maptype_id;
+ binary_buf_t key = input->key;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ size_t key_size;
+ iod_kv_t kv;
+ iod_kv_params_t kvs;
+ iod_ret_t ret;
+ iod_checksum_t cs;
+ hbool_t opened_locally = FALSE;
+ hbool_t is_vl_data = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map delete \n");
+#endif
+
+ /* open the map if we don't have the handle yet */
+ if(iod_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_write(coh, iod_id, rtid, NULL /*hints*/, &iod_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ /* adjust buffers for datatype conversion */
+ if(H5VL__iod_server_adjust_buffer(key_memtype_id, key_maptype_id, 1, H5P_DEFAULT,
+ key.buf_size, &key.buf, &is_vl_data, &key_size) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ kv.key = key.buf;
+ kv.key_len = key_size;
+ kvs.kv = &kv;
+ kvs.cs = &cs;
+ kvs.ret = &ret;
+
+ if(iod_kv_unlink_keys(iod_oh, wtid, NULL, 1, &kvs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+
+ if(ret < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair");
+done:
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map delete, sending %d response to client\n", ret_value);
+#endif
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map delete");
+
+ input = (map_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the map if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(iod_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_delete_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_close_cb
+ *
+ * Purpose: Closes iod HDF5 map.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_map_close_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ map_close_in_t *input = (map_close_in_t *)op_data->input;
+ iod_handles_t iod_oh = input->iod_oh;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start map Close %"PRIu64" %"PRIu64"\n",
+ iod_oh.rd_oh.cookie, iod_oh.wr_oh.cookie);
+#endif
+
+ if((iod_obj_close(iod_oh.rd_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ if((iod_obj_close(iod_oh.wr_oh, NULL, NULL)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with map close, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (map_close_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_map_close_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_obj.c b/src/H5VLiod_obj.c
new file mode 100644
index 0000000..2ec9340
--- /dev/null
+++ b/src/H5VLiod_obj.c
@@ -0,0 +1,982 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * June, 2013
+ *
+ * Purpose: The IOD plugin server side general object routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_open_cb
+ *
+ * Purpose: Opens an existing object in the container
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_open_by_token_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_token_in_t *input = (object_token_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_obj_id_t obj_id = input->iod_id; /* The ID of the object */
+ iod_trans_id_t tid = input->trans_num;
+ //uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh; /* The handle for object */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Open by token = %"PRIx64"\n", obj_id);
+#endif
+
+ if (iod_obj_open_read(coh, obj_id, tid, NULL /*hints*/, &obj_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ if (iod_obj_open_write(coh, obj_id, tid, NULL /*hints*/, &obj_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with object open by token, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &obj_oh);
+
+done:
+ if(ret_value < 0) {
+ obj_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ obj_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(op_data->hg_handle, &obj_oh);
+ }
+
+ input = (object_token_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_open_cb
+ *
+ * Purpose: Opens an existing object in the container
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_open_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_op_in_t *input = (object_op_in_t *)op_data->input;
+ object_open_out_t output;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh; /* The handle for object */
+ iod_obj_id_t obj_id; /* The ID of the object */
+ iod_handle_t mdkv_oh;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Open on %s (OH %"PRIu64" ID %"PRIx64")\n",
+ input->loc_name, input->loc_oh.rd_oh.cookie, input->loc_id);
+#endif
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, input->loc_id, input->loc_oh, input->loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if (iod_obj_open_write(coh, obj_id, rtid, NULL, &obj_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ if(obj_id != input->loc_id) {
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+ else {
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, input->loc_mdkv_id, rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_OBJECT_TYPE, H5VL_IOD_KEY_OBJ_TYPE,
+ cs_scope, NULL, &output.obj_type) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ switch(output.obj_type) {
+ case H5I_MAP:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve mcpl");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_MAP_KEY_TYPE,
+ cs_scope, NULL, &output.id1) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE,
+ H5VL_IOD_KEY_MAP_VALUE_TYPE,
+ cs_scope, NULL, &output.id2) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+ break;
+ case H5I_GROUP:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl");
+ output.id1 = FAIL;
+ output.id2 = FAIL;
+ break;
+ case H5I_DATASET:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE, H5VL_IOD_KEY_OBJ_DATATYPE,
+ cs_scope, NULL, &output.id1) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE, H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &output.id2) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+ break;
+ case H5I_DATATYPE:
+ {
+ size_t buf_size; /* size of serialized datatype */
+ void *buf = NULL;
+ iod_mem_desc_t *mem_desc = NULL; /* memory descriptor used for reading */
+ iod_blob_iodesc_t *file_desc = NULL; /* file descriptor used to write */
+ iod_checksum_t dt_cs = 0, blob_cs = 0;
+ iod_size_t key_size, val_size;
+ iod_checksum_t iod_cs[2];
+
+ key_size = strlen(H5VL_IOD_KEY_DTYPE_SIZE);
+ val_size = sizeof(iod_size_t);
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl");
+
+ /* retrieve blob size metadata from scratch pad */
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "datatype size lookup failed");
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate BLOB read buffer");
+
+ /* create memory descriptor for writing */
+ mem_desc = (iod_mem_desc_t *)malloc(sizeof(iod_mem_desc_t) +
+ sizeof(iod_mem_frag_t));
+ mem_desc->nfrag = 1;
+ mem_desc->frag[0].addr = buf;
+ mem_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* create file descriptor for writing */
+ file_desc = (iod_blob_iodesc_t *)malloc(sizeof(iod_blob_iodesc_t) +
+ sizeof(iod_blob_iofrag_t));
+ file_desc->nfrag = 1;
+ file_desc->frag[0].offset = 0;
+ file_desc->frag[0].len = (iod_size_t)buf_size;
+
+ /* read the serialized type value from the BLOB object */
+ if(iod_blob_read(obj_oh.rd_oh, rtid, NULL, mem_desc, file_desc,
+ &blob_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read BLOB object");
+
+ if(blob_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* calculate a checksum for the datatype */
+ dt_cs = H5_checksum_crc64(buf, buf_size);
+
+ /* Verify checksum against one given by IOD */
+ if(blob_cs != dt_cs)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "Data Corruption detected when reading datatype");
+ }
+
+ /* decode the datatype */
+ if((output.id1 = H5Tdecode(buf)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to decode datatype");
+ output.id2 = FAIL;
+
+ free(mem_desc);
+ free(file_desc);
+ free(buf);
+ break;
+ }
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Invalid object type");
+ }
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ output.iod_id = obj_id;
+ output.mdkv_id = sp[0];
+ output.attrkv_id = sp[1];
+ output.iod_oh.rd_oh.cookie = obj_oh.rd_oh.cookie;
+ output.iod_oh.wr_oh.cookie = obj_oh.wr_oh.cookie;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with object open, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ if(ret_value < 0) {
+ output.iod_oh.rd_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_oh.wr_oh.cookie = IOD_OH_UNDEFINED;
+ output.iod_id = IOD_OBJ_INVALID;
+ output.cpl_id = FAIL;
+ output.id1 = FAIL;
+ output.id2 = FAIL;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (object_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_open_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_copy_cb
+ *
+ * Purpose: Moves/Copies a link in the container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_copy_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_copy_in_t *input = (object_copy_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t dst_oh; /* The handle for the dst object where link is created*/
+ iod_obj_id_t dst_id; /* The ID of the dst object where link is created*/
+ iod_obj_id_t obj_id; /* The ID of the object to be moved/copied */
+ iod_handles_t obj_oh; /* The handle for the object to be moved/copied */
+ iod_obj_id_t new_id; /* The ID of the new object */
+ iod_handle_t mdkv_oh;/* The handle of the metadata KV for source object */
+ char *new_name = NULL;
+ iod_kv_t kv;
+ iod_size_t kv_size = sizeof(H5VL_iod_link_t);
+ H5VL_iod_link_t iod_link;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start object copy\n");
+#endif
+
+ /* MSC - NEED IOD & a lot more work*/
+#if 0
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, input->src_loc_id, input->src_loc_oh, input->src_loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ /* the traversal will retrieve the location where the objects
+ needs to be copied to. The traversal will fail if an
+ intermediate group does not exist. */
+ if(H5VL_iod_server_traverse(coh, input->dst_loc_id, input->dst_loc_oh, input->dst_loc_name,
+ FALSE, rtid, &new_name, &dst_id, &dst_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path");
+
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_write(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_OBJECT_TYPE, H5VL_IOD_KEY_OBJ_TYPE,
+ cs_scope, NULL, &obj_type) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ switch(obj_type) {
+ case H5I_MAP:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve mcpl");
+ break;
+ case H5I_GROUP:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve gcpl");
+ break;
+ case H5I_DATASET:
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_PLIST, H5VL_IOD_KEY_OBJ_CPL,
+ cs_scope, NULL, &output.cpl_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE, H5VL_IOD_KEY_OBJ_DATATYPE,
+ cs_scope, NULL, &output.type_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATASPACE, H5VL_IOD_KEY_OBJ_DATASPACE,
+ cs_scope, NULL, &output.space_id) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace");
+ break;
+ case H5I_DATATYPE:
+ {
+ size_t buf_size; /* size of serialized datatype */
+ void *buf = NULL;
+ iod_mem_desc_t mem_desc; /* memory descriptor used for reading */
+ iod_blob_iodesc_t file_desc; /* file descriptor used to write */
+ iod_checksum_t dt_cs = 0, blob_cs = 0;
+ iod_checksum_t iod_cs[2];
+
+ /* retrieve blob size metadata from scratch pad */
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "datatype size lookup failed");
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_DTYPE_SIZE, key_size,
+ &buf_size, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate BLOB read buffer");
+
+ /* create memory descriptor for reading */
+ mem_desc.nfrag = 1;
+ mem_desc.frag->addr = buf;
+ mem_desc.frag->len = (iod_size_t)buf_size;
+
+ /* create file descriptor for writing */
+ file_desc.nfrag = 1;
+ file_desc.frag->offset = 0;
+ file_desc.frag->len = (iod_size_t)buf_size;
+
+ /* read the serialized type value from the BLOB object */
+ if(iod_blob_read(obj_oh, rtid, NULL, &mem_desc, &file_desc, NULL,
+ &blob_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object");
+
+ if(blob_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* calculate a checksum for the datatype */
+ dt_cs = H5_checksum_crc64(buf, buf_size);
+
+ /* Verify checksum against one given by IOD */
+ if(blob_cs != dt_cs)
+ HGOTO_ERROR2(H5E_SYM, H5E_READERROR, FAIL, "Data Corruption detected when reading datatype");
+ }
+
+ /* decode the datatype */
+ if((output.type_id = H5Tdecode(buf)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unable to decode datatype");
+
+ free(buf);
+ }
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Invalid object type");
+ }
+
+ /* create new object as a copy of the source object */
+ /* MSC - wait to see if IOD will have an object copy */
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ /* close the object handle */
+ if(input->src_loc_oh.cookie != obj_oh.cookie &&
+ iod_obj_close(obj_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* Insert object in the destination path */
+ if(H5VL_iod_insert_new_link(dst_oh, wtid, new_name,
+ H5L_TYPE_HARD, &obj_id, cs_scope, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value");
+
+ /* close dst group if it is not the location we started the
+ traversal into */
+ if(input->dst_loc_oh.cookie != dst_oh.cookie) {
+ iod_obj_close(dst_oh, NULL, NULL);
+ }
+
+#endif
+
+done:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with object Copy, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ if(new_name)
+ free(new_name);
+ input = (object_copy_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_copy_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_exists_cb
+ *
+ * Purpose: Checks if an object exists.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_exists_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_op_in_t *input = (object_op_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh;
+ iod_obj_id_t obj_id;
+ const char *loc_name = input->loc_name;
+ htri_t ret = -1;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Exists on %s (OH %"PRIu64" ID %"PRIx64")\n",
+ input->loc_name, input->loc_oh.rd_oh.cookie, input->loc_id);
+#endif
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_oh, loc_name, rtid,
+ cs_scope, &obj_id, &obj_oh) < 0) {
+ ret = FALSE;
+ HGOTO_DONE(SUCCEED);
+ }
+ else {
+ /* close the object */
+ if(loc_oh.rd_oh.cookie != obj_oh.rd_oh.cookie &&
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* set return to TRUE */
+ ret = TRUE;
+ }
+
+done:
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Object exists, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret);
+
+ input = (object_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_exists_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_get_info_cb
+ *
+ * Purpose: Checks if an object get_info.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_get_info_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_op_in_t *input = (object_op_in_t *)op_data->input;
+ H5O_ff_info_t oinfo;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh;
+ iod_handle_t mdkv_oh, attrkv_oh;
+ iod_obj_id_t obj_id;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ H5I_type_t obj_type;
+ int num_attrs = 0;
+ const char *loc_name = input->loc_name;
+ uint64_t link_count = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Get Info on %s (OH %"PRIu64" ID %"PRIx64")\n",
+ input->loc_name, input->loc_oh.rd_oh.cookie, input->loc_id);
+#endif
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_oh, loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "object does not exist");
+
+ oinfo.addr = obj_id;
+
+ if(obj_id != loc_id || input->loc_mdkv_id == IOD_OBJ_INVALID) {
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, sp[1], rtid, NULL, &attrkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open ATTRKV");
+ }
+ else {
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, input->loc_mdkv_id, rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ /* open the attribute KV */
+ if (iod_obj_open_read(coh, input->loc_attrkv_id, rtid, NULL, &attrkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_OBJECT_TYPE,
+ H5VL_IOD_KEY_OBJ_TYPE,
+ cs_scope, NULL, &obj_type) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve object type");
+
+ switch(obj_type) {
+ case H5I_GROUP:
+ oinfo.type = H5O_TYPE_GROUP;
+ break;
+ case H5I_DATASET:
+ oinfo.type = H5O_TYPE_DATASET;
+ break;
+ case H5I_DATATYPE:
+ oinfo.type = H5O_TYPE_NAMED_DATATYPE;
+ break;
+ case H5I_MAP:
+ oinfo.type = H5O_TYPE_MAP;
+ break;
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL,
+ "unsupported object type for H5Oget_info");
+ }
+
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_LINK_COUNT,
+ H5VL_IOD_KEY_OBJ_LINK_COUNT,
+ cs_scope, NULL, &link_count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count");
+
+ oinfo.rc = (unsigned) link_count;
+
+ if(iod_kv_get_num(attrkv_oh, rtid, &num_attrs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve attribute count");
+
+ oinfo.num_attrs = (hsize_t)num_attrs;
+
+ /* close the metadata KV */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+ /* close the attribute KV */
+ if(iod_obj_close(attrkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ if(loc_oh.rd_oh.cookie != obj_oh.rd_oh.cookie &&
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Object get_info, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &oinfo);
+
+done:
+ if(ret_value < 0) {
+ oinfo.type = H5O_TYPE_UNKNOWN;
+ oinfo.addr = IOD_OBJ_INVALID;
+ oinfo.rc = 0;
+ oinfo.num_attrs = 0;
+ HG_Handler_start_output(op_data->hg_handle, &oinfo);
+ }
+
+ input = (object_op_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_get_info_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_set_comment_cb
+ *
+ * Purpose: Set comment for an object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_set_comment_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_set_comment_in_t *input = (object_set_comment_in_t *)op_data->input;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ iod_trans_id_t wtid = input->trans_num;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handles_t obj_oh;
+ iod_handle_t mdkv_oh;
+ iod_obj_id_t obj_id;
+ const char *loc_name = input->path;
+ const char *comment = input->comment;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Set comment on %s (OH %"PRIu64" ID %"PRIx64")\n",
+ input->path, input->loc_oh.rd_oh.cookie, input->loc_id);
+#endif
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_oh, loc_name, rtid,
+ cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if(loc_id != obj_id || input->loc_mdkv_id == IOD_OBJ_INVALID) {
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_write(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+ else {
+ /* open the metadata KV */
+ if (iod_obj_open_write(coh, input->loc_mdkv_id, rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+
+ {
+ iod_kv_t kv;
+
+ kv.key = H5VL_IOD_KEY_OBJ_COMMENT;
+ kv.key_len = strlen(H5VL_IOD_KEY_OBJ_COMMENT);
+ kv.value_len = strlen(comment) + 1;
+ kv.value = comment;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ if (iod_kv_set(mdkv_oh, wtid, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(mdkv_oh, wtid, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set comment in MDKV");
+ }
+
+ }
+
+ /* close metadata KV and object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ if(loc_oh.rd_oh.cookie != obj_oh.rd_oh.cookie &&
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+done:
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with set comment, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (object_set_comment_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_set_comment_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_get_comment_cb
+ *
+ * Purpose: Get comment for an object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_object_get_comment_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ object_get_comment_in_t *input = (object_get_comment_in_t *)op_data->input;
+ object_get_comment_out_t output;
+ name_t comment;
+ iod_handle_t coh = input->coh;
+ iod_handles_t loc_oh = input->loc_oh;
+ iod_obj_id_t loc_id = input->loc_id;
+ size_t length = input->length;
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ iod_handle_t mdkv_oh;
+ iod_handles_t obj_oh;
+ iod_obj_id_t obj_id;
+ const char *loc_name = input->path;
+ scratch_pad sp;
+ iod_checksum_t sp_cs = 0;
+ iod_size_t key_size, val_size = 0;
+ void *value = NULL;
+ iod_checksum_t *iod_cs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Start Object Get comment on %s (OH %"PRIu64" ID %"PRIx64")\n",
+ input->path, input->loc_oh.rd_oh.cookie, input->loc_id);
+#endif
+
+ /* Traverse Path and open object */
+ if(H5VL_iod_server_open_path(coh, loc_id, loc_oh, loc_name,
+ rtid, cs_scope, &obj_id, &obj_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ if(loc_id != obj_id || input->loc_mdkv_id == IOD_OBJ_INVALID) {
+ /* get scratch pad of the object */
+ if(iod_obj_get_scratch(obj_oh.rd_oh, rtid, &sp, &sp_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ if(sp_cs && (cs_scope & H5_CHECKSUM_IOD)) {
+ /* verify scratch pad integrity */
+ if(H5VL_iod_verify_scratch_pad(&sp, sp_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Scratch Pad failed integrity check");
+ }
+
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, sp[0], rtid, NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+ else {
+ /* open the metadata KV */
+ if (iod_obj_open_read(coh, input->loc_mdkv_id, rtid, NULL, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open MDKV");
+ }
+
+ comment.value_size = (ssize_t *)malloc(sizeof(ssize_t));
+ comment.value = NULL;
+ comment.size = length;
+
+ key_size = strlen(H5VL_IOD_KEY_OBJ_COMMENT);
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_cs = (iod_checksum_t *)malloc(sizeof(iod_checksum_t) * 2);
+ }
+
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_OBJ_COMMENT, key_size,
+ NULL, &val_size, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "comment size lookup failed");
+
+ if(NULL == (value = malloc ((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(mdkv_oh, rtid, H5VL_IOD_KEY_OBJ_COMMENT, key_size,
+ value, &val_size, iod_cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "comment value lookup failed");
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ if(H5VL_iod_verify_kv_pair(H5VL_IOD_KEY_OBJ_COMMENT, key_size,
+ value, val_size, iod_cs) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+ if(length) {
+ if(NULL == (comment.value = (char *)malloc (length)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+ memcpy(comment.value, value, length);
+ }
+
+ free(value);
+
+ /* close metadata KV and object */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ if(loc_oh.rd_oh.cookie != obj_oh.rd_oh.cookie &&
+ iod_obj_close(obj_oh.rd_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ *comment.value_size = (ssize_t)val_size;
+
+done:
+ output.ret = ret_value;
+ output.name = comment;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with get comment, sending response to client\n");
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+ if(comment.value) {
+ free(comment.value);
+ comment.value = NULL;
+ }
+
+ if(comment.value_size) {
+ free(comment.value_size);
+ comment.value_size = NULL;
+ }
+
+ if(iod_cs) {
+ free(iod_cs);
+ iod_cs = NULL;
+ }
+
+ input = (object_get_comment_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_object_get_comment_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_server.c b/src/H5VLiod_server.c
new file mode 100644
index 0000000..ad71811
--- /dev/null
+++ b/src/H5VLiod_server.c
@@ -0,0 +1,3795 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_PYTHON
+#include <Python.h>
+#endif
+
+#define MAX_LOC_NAME 256
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * February, 2013
+ *
+ * Purpose: The IOD plugin server side routines.
+ */
+
+static AXE_engine_t engine;
+static MPI_Comm iod_comm;
+static int num_peers = 0;
+static int terminate_requests = 0;
+static hbool_t shutdown = FALSE;
+
+iod_obj_id_t ROOT_ID = 0;
+
+int num_ions_g = 0;
+int my_rank_g = 0;
+na_addr_t *server_addr_g = NULL;
+char **server_loc_g = NULL;
+hg_id_t H5VL_EFF_OPEN_CONTAINER;
+hg_id_t H5VL_EFF_CLOSE_CONTAINER;
+hg_id_t H5VL_EFF_ANALYSIS_FARM;
+hg_id_t H5VL_EFF_ANALYSIS_FARM_TRANSFER;
+
+void
+EFF__mercury_register_callbacks(void)
+{
+
+ H5VL_EFF_OPEN_CONTAINER = MERCURY_REGISTER("container_open", hg_const_string_t, iod_handle_t);
+ MERCURY_HANDLER_REGISTER("container_open", H5VL_iod_server_container_open,
+ hg_const_string_t, iod_handle_t);
+
+ H5VL_EFF_CLOSE_CONTAINER = MERCURY_REGISTER("container_close", iod_handle_t, ret_t);
+ MERCURY_HANDLER_REGISTER("container_close", H5VL_iod_server_container_close,
+ iod_handle_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("analysis_execute", H5VL_iod_server_analysis_execute,
+ analysis_execute_in_t, analysis_execute_out_t);
+
+ H5VL_EFF_ANALYSIS_FARM = MERCURY_REGISTER("analysis_farm", analysis_farm_in_t,
+ analysis_farm_out_t);
+ MERCURY_HANDLER_REGISTER("analysis_farm", H5VL_iod_server_analysis_farm,
+ analysis_farm_in_t, analysis_farm_out_t);
+
+ H5VL_EFF_ANALYSIS_FARM_TRANSFER = MERCURY_REGISTER("analysis_transfer",
+ analysis_transfer_in_t, analysis_transfer_out_t);
+ MERCURY_HANDLER_REGISTER("analysis_transfer", H5VL_iod_server_analysis_transfer,
+ analysis_transfer_in_t, analysis_transfer_out_t);
+
+ /* Register function and encoding/decoding functions */
+ MERCURY_HANDLER_REGISTER("eff_init", H5VL_iod_server_eff_init,
+ eff_init_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("eff_finalize", H5VL_iod_server_eff_finalize,
+ ret_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("file_create", H5VL_iod_server_file_create,
+ file_create_in_t, file_create_out_t);
+ MERCURY_HANDLER_REGISTER("file_open", H5VL_iod_server_file_open,
+ file_open_in_t, file_open_out_t);
+ MERCURY_HANDLER_REGISTER("file_close", H5VL_iod_server_file_close,
+ file_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("attr_create", H5VL_iod_server_attr_create,
+ attr_create_in_t, attr_create_out_t);
+ MERCURY_HANDLER_REGISTER("attr_open", H5VL_iod_server_attr_open,
+ attr_open_in_t, attr_open_out_t);
+ MERCURY_HANDLER_REGISTER("attr_read", H5VL_iod_server_attr_read,
+ attr_io_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("attr_write", H5VL_iod_server_attr_write,
+ attr_io_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("attr_exists", H5VL_iod_server_attr_exists,
+ attr_op_in_t, htri_t);
+ MERCURY_HANDLER_REGISTER("attr_rename", H5VL_iod_server_attr_rename,
+ attr_rename_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("attr_remove", H5VL_iod_server_attr_remove,
+ attr_op_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("attr_close", H5VL_iod_server_attr_close,
+ attr_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("group_create", H5VL_iod_server_group_create,
+ group_create_in_t, group_create_out_t);
+ MERCURY_HANDLER_REGISTER("group_open", H5VL_iod_server_group_open,
+ group_open_in_t, group_open_out_t);
+ MERCURY_HANDLER_REGISTER("group_close", H5VL_iod_server_group_close,
+ group_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("map_create", H5VL_iod_server_map_create,
+ map_create_in_t, map_create_out_t);
+ MERCURY_HANDLER_REGISTER("map_open", H5VL_iod_server_map_open,
+ map_open_in_t, map_open_out_t);
+ MERCURY_HANDLER_REGISTER("map_set", H5VL_iod_server_map_set,
+ map_set_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("map_get", H5VL_iod_server_map_get,
+ map_get_in_t, map_get_out_t);
+ MERCURY_HANDLER_REGISTER("map_get_count", H5VL_iod_server_map_get_count,
+ map_get_count_in_t, int64_t);
+ MERCURY_HANDLER_REGISTER("map_exists", H5VL_iod_server_map_exists,
+ map_op_in_t, hbool_t);
+ MERCURY_HANDLER_REGISTER("map_delete", H5VL_iod_server_map_delete,
+ map_op_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("map_close", H5VL_iod_server_map_close,
+ map_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("dset_create", H5VL_iod_server_dset_create,
+ dset_create_in_t, dset_create_out_t);
+ MERCURY_HANDLER_REGISTER("dset_open", H5VL_iod_server_dset_open,
+ dset_open_in_t, dset_open_out_t);
+ MERCURY_HANDLER_REGISTER("dset_read", H5VL_iod_server_dset_read,
+ dset_io_in_t, dset_read_out_t);
+ MERCURY_HANDLER_REGISTER("dset_get_vl_size", H5VL_iod_server_dset_get_vl_size,
+ dset_io_in_t, dset_read_out_t);
+ MERCURY_HANDLER_REGISTER("dset_write", H5VL_iod_server_dset_write,
+ dset_io_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("dset_set_extent", H5VL_iod_server_dset_set_extent,
+ dset_set_extent_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("dset_close", H5VL_iod_server_dset_close,
+ dset_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("dtype_commit", H5VL_iod_server_dtype_commit,
+ dtype_commit_in_t, dtype_commit_out_t);
+ MERCURY_HANDLER_REGISTER("dtype_open", H5VL_iod_server_dtype_open,
+ dtype_open_in_t, dtype_open_out_t);
+ MERCURY_HANDLER_REGISTER("dtype_close", H5VL_iod_server_dtype_close,
+ dtype_close_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("link_create", H5VL_iod_server_link_create,
+ link_create_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("link_move", H5VL_iod_server_link_move,
+ link_move_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("link_exists", H5VL_iod_server_link_exists,
+ link_op_in_t, htri_t);
+ MERCURY_HANDLER_REGISTER("link_get_info", H5VL_iod_server_link_get_info,
+ link_op_in_t, linfo_t);
+ MERCURY_HANDLER_REGISTER("link_get_val", H5VL_iod_server_link_get_val,
+ link_get_val_in_t, link_get_val_out_t);
+ MERCURY_HANDLER_REGISTER("link_iterate", H5VL_iod_server_link_iterate,
+ link_op_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("link_remove", H5VL_iod_server_link_remove,
+ link_op_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("object_open_by_token", H5VL_iod_server_object_open_by_token,
+ object_token_in_t, iod_handles_t);
+ MERCURY_HANDLER_REGISTER("object_open", H5VL_iod_server_object_open,
+ object_op_in_t, object_open_out_t);
+ MERCURY_HANDLER_REGISTER("object_copy", H5VL_iod_server_object_copy,
+ object_copy_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("object_exists", H5VL_iod_server_object_exists,
+ object_op_in_t, htri_t);
+ MERCURY_HANDLER_REGISTER("object_visit", H5VL_iod_server_object_visit,
+ object_op_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("set_comment", H5VL_iod_server_object_set_comment,
+ object_set_comment_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("get_comment", H5VL_iod_server_object_get_comment,
+ object_get_comment_in_t, object_get_comment_out_t);
+ MERCURY_HANDLER_REGISTER("object_get_info", H5VL_iod_server_object_get_info,
+ object_op_in_t, oinfo_t);
+
+ MERCURY_HANDLER_REGISTER("read_context_acquire", H5VL_iod_server_rcxt_acquire,
+ rc_acquire_in_t, rc_acquire_out_t);
+ MERCURY_HANDLER_REGISTER("read_context_release", H5VL_iod_server_rcxt_release,
+ rc_release_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("read_context_persist", H5VL_iod_server_rcxt_persist,
+ rc_persist_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("read_context_snapshot", H5VL_iod_server_rcxt_snapshot,
+ rc_snapshot_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("transaction_start", H5VL_iod_server_trans_start,
+ tr_start_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("transaction_finish", H5VL_iod_server_trans_finish,
+ tr_finish_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("transaction_set_depend", H5VL_iod_server_trans_set_dependency,
+ tr_set_depend_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("transaction_skip", H5VL_iod_server_trans_skip,
+ tr_skip_in_t, ret_t);
+ MERCURY_HANDLER_REGISTER("transaction_abort", H5VL_iod_server_trans_abort,
+ tr_abort_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("prefetch", H5VL_iod_server_prefetch,
+ prefetch_in_t, hrpl_t);
+ MERCURY_HANDLER_REGISTER("evict", H5VL_iod_server_evict,
+ evict_in_t, ret_t);
+
+ MERCURY_HANDLER_REGISTER("cancel_op", H5VL_iod_server_cancel_op, uint64_t, uint8_t);
+}
+
+herr_t
+EFF_start_server(MPI_Comm comm, MPI_Info UNUSED info)
+{
+ na_class_t *network_class = NULL;
+ AXE_engine_attr_t engine_attr;
+ int i;
+ const char *addr_name;
+ char **na_addr_table = NULL;
+ FILE *config = NULL;
+ herr_t ret_value = SUCCEED;
+
+ MPI_Comm_size(comm, &num_ions_g);
+ MPI_Comm_rank(comm, &my_rank_g);
+
+ /******************* Initialize mercury ********************/
+ /* initialize the netwrok class */
+ network_class = NA_MPI_Init(NULL, MPI_INIT_SERVER);
+
+ /* Allocate table addrs */
+ na_addr_table = (char**) malloc((size_t)num_ions_g * sizeof(char*));
+ for (i = 0; i < num_ions_g; i++) {
+ na_addr_table[i] = (char*) malloc(MPI_MAX_PORT_NAME);
+ }
+
+ addr_name = NA_MPI_Get_port_name(network_class);
+ strcpy(na_addr_table[my_rank_g], addr_name);
+
+#ifdef NA_HAS_MPI
+ for (i = 0; i < num_ions_g; i++) {
+ MPI_Bcast(na_addr_table[i], MPI_MAX_PORT_NAME,
+ MPI_BYTE, i, comm);
+ }
+#endif
+
+ /* Only rank 0 writes file */
+ if (my_rank_g == 0) {
+ config = fopen("port.cfg", "w+");
+ if (config != NULL) {
+ fprintf(config, "%d\n", num_ions_g);
+ for (i = 0; i < num_ions_g; i++) {
+ fprintf(config, "%s\n", na_addr_table[i]);
+ }
+ fclose(config);
+ }
+ }
+
+ iod_comm = comm;
+
+ if(HG_SUCCESS != HG_Init(network_class))
+ return FAIL;
+ if(HG_SUCCESS != HG_Handler_init(network_class))
+ return FAIL;
+
+ /* Look up addr id */
+ /* We do the lookup here but this may not be optimal */
+ server_addr_g = (na_addr_t *) malloc((size_t)num_ions_g * sizeof(na_addr_t));
+ for (i = 0; i < num_ions_g; i++) {
+ if(NA_SUCCESS != NA_Addr_lookup_wait(network_class, na_addr_table[i], &server_addr_g[i])) {
+ fprintf(stderr, "Could not find addr\n");
+ return FAIL;
+ }
+ }
+
+ /* Get array of loc string */
+ server_loc_g = (char **) malloc((unsigned int) num_ions_g * sizeof(char *));
+ for (i = 0; i < num_ions_g; i++) {
+ server_loc_g[i] = (char *) malloc(MAX_LOC_NAME);
+ }
+
+ /* Only rank 0 read loc file */
+ if (my_rank_g == 0) {
+ config = fopen("loc.cfg", "r+");
+ if (!config) {
+ fprintf(stderr, "Warning, no loc config was found\n");
+ } else {
+ for (i = 0; i < num_ions_g; i++) {
+ fscanf(config, "%s\n", server_loc_g[i]);
+ }
+ fclose(config);
+ }
+ }
+ /* TODO may not be necessary to do a broadcast here */
+ for (i = 0; i < num_ions_g; i++)
+ MPI_Bcast(server_loc_g[i], MAX_LOC_NAME, MPI_BYTE, 0, comm);
+
+
+ /***************** END Initialize mercury *******************/
+
+ EFF__mercury_register_callbacks();
+
+ /* Initialize engine attribute */
+ if(AXEengine_attr_init(&engine_attr) != AXE_SUCCEED)
+ return FAIL;
+
+ /* Set number of threads in AXE engine */
+ if(AXEset_num_threads(&engine_attr, 4) != AXE_SUCCEED)
+ return FAIL;
+
+ /* Create AXE engine */
+ if(AXEcreate_engine(&engine, &engine_attr) != AXE_SUCCEED)
+ return FAIL;
+
+ /* Initialize Python runtime */
+#ifdef H5_HAVE_PYTHON
+ Py_Initialize();
+#endif
+
+ /* Loop to receive requests from clients */
+ while(1) {
+ HG_Handler_process(0, HG_STATUS_IGNORE);
+ if(shutdown)
+ break;
+ }
+
+ /* Finalize Python runtime */
+#ifdef H5_HAVE_PYTHON
+ Py_Finalize();
+#endif
+
+ if(AXE_SUCCEED != AXEterminate_engine(engine, TRUE))
+ return FAIL;
+
+ if(AXEengine_attr_destroy(&engine_attr) != AXE_SUCCEED)
+ return FAIL;
+
+ /******************* Finalize mercury ********************/
+ for (i = 0; i < num_ions_g; i++) {
+ free(server_loc_g[i]);
+ }
+ free(server_loc_g);
+
+ for (i = 0; i < num_ions_g; i++) {
+ NA_Addr_free(network_class, server_addr_g[i]);
+ }
+ free(server_addr_g);
+
+ if(HG_SUCCESS != HG_Handler_finalize())
+ return FAIL;
+ if(HG_SUCCESS != HG_Finalize())
+ return FAIL;
+ if(NA_SUCCESS != NA_Finalize(network_class))
+ return FAIL;
+
+ if (na_addr_table) {
+ for (i = 0; i < num_ions_g; i++) {
+ free(na_addr_table[i]);
+ }
+ free(na_addr_table);
+ na_addr_table = NULL;
+ num_ions_g = 0;
+ }
+ /***************** END Finalize mercury *******************/
+
+ return ret_value;
+}
+
+static herr_t
+H5VL__iod_server_finish_axe_tasks(AXE_engine_t axe_engine, AXE_task_t start_range,
+ size_t count)
+{
+ AXE_task_t u;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ for(u=start_range ; u<count+start_range ; u++) {
+ if(AXE_SUCCEED != AXEfinish(axe_engine, u))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE task");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_server_finish_axe_tasks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_eff_init
+ *
+ * Purpose: Function shipper registered call for initializing the eff stack.
+ * this will initialize the IOD library
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_eff_init(hg_handle_t handle)
+{
+ uint32_t num_procs;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the input from the client connecting */
+ if(HG_FAIL == HG_Handler_get_input(handle, &num_procs))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ /* initialize the IOD library */
+ if(iod_initialize(iod_comm, NULL, num_procs, num_procs) < 0)
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't initialize");
+
+ /* set the root ID */
+ IOD_OBJID_SETOWNER_APP(ROOT_ID)
+ IOD_OBJID_SETTYPE(ROOT_ID, IOD_OBJ_KV)
+
+ num_peers ++;
+
+done:
+ HG_Handler_start_output(handle, &ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_eff_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_eff_finalize
+ *
+ * Purpose: Function to shutdown server
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_eff_finalize(hg_handle_t handle)
+{
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* increment the number of terminate requests received so far */
+ terminate_requests ++;
+
+ if(iod_finalize(NULL) < 0 )
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTDEC, HG_FAIL, "can't finalize IOD");
+
+ /* if all the peers that connected at the beginning have sent the
+ terminate request, then finalize IOD and indicate that it is
+ time to shutdown the server */
+ if(terminate_requests == num_peers) {
+ shutdown = TRUE;
+ }
+
+done:
+ HG_Handler_start_output(handle, &ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_eff_finalize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_execute
+ *
+ * Purpose: Function shipper registered call for Executing Analysis.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_analysis_execute(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ analysis_execute_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (analysis_execute_in_t *)H5MM_malloc(sizeof(analysis_execute_in_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ //if(AXE_SUCCEED != AXEgenerate_task_id(engine, &axe_id))
+ //HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to generate ID for AXE task");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id, 0, NULL, 0, NULL,
+ H5VL_iod_server_analysis_execute_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_analysis_execute() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_farm
+ *
+ * Purpose: Function shipper registered call for Analysis Farming.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_analysis_farm(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ analysis_farm_in_t *input = NULL;
+ AXE_task_t axe_id;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (analysis_farm_in_t *)H5MM_malloc(sizeof(analysis_farm_in_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(AXE_SUCCEED != AXEgenerate_task_id(engine, &axe_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to generate ID for AXE task");
+
+ op_data->hg_handle = handle;
+ op_data->axe_id = axe_id;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, axe_id, 0, NULL, 0, NULL,
+ H5VL_iod_server_analysis_farm_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_analysis_farm() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_analysis_transfer
+ *
+ * Purpose: Function shipper registered call for Analysis Farming.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_analysis_transfer(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ AXE_task_t *input = NULL;
+ AXE_task_t axe_id;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (AXE_task_t *)H5MM_malloc(sizeof(AXE_task_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if(AXE_SUCCEED != AXEgenerate_task_id(engine, &axe_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to generate ID for AXE task");
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, axe_id, 0, NULL, 0, NULL,
+ H5VL_iod_server_analysis_transfer_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_analysis_transfer() */
+
+int
+H5VL_iod_server_container_open(hg_handle_t handle)
+{
+ const char *file_name;
+ iod_handle_t coh;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(HG_FAIL == HG_Handler_get_input(handle, &file_name))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ /* open the container */
+ printf("Calling iod_container_open on %s\n", file_name);
+ if(iod_container_open(file_name, NULL, IOD_CONT_R, &coh, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open file");
+
+ HG_Handler_start_output(handle, &coh);
+
+done:
+ if(ret_value < 0) {
+ coh.cookie = IOD_OH_UNDEFINED;
+ HG_Handler_start_output(handle, &coh);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_container_open() */
+
+int
+H5VL_iod_server_container_close(hg_handle_t handle)
+{
+ iod_handle_t coh;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(HG_FAIL == HG_Handler_get_input(handle, &coh))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ /* open the container */
+ if(iod_container_close(coh, NULL, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, FAIL, "can't open file");
+
+done:
+ HG_Handler_start_output(handle, &ret_value);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_container_open() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_cancel_op
+ *
+ * Purpose: Function to cancel an AXE operation
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_cancel_op(hg_handle_t handle)
+{
+ AXE_task_t axe_id;
+ AXE_remove_status_t remove_status;
+ H5ES_status_t status = H5ES_STATUS_IN_PROGRESS;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(HG_FAIL == HG_Handler_get_input(handle, &axe_id))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ /* Try to remove the task. */
+ if(AXEremove(engine, axe_id, &remove_status) != AXE_SUCCEED)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTREMOVE, HG_FAIL, "can't remove AXE task; it has children");
+
+ if(remove_status == AXE_CANCELED)
+ HGOTO_DONE(H5VL_IOD_CANCELLED)
+ else if(remove_status == AXE_ALL_DONE)
+ HGOTO_DONE(H5VL_IOD_COMPLETED)
+ else if(remove_status == AXE_NOT_CANCELED) {
+ void *op_data;
+
+ fprintf(stderr, "Task is running. Attempting to cancel Manually\n");
+ if(AXEget_op_data(engine, axe_id, &op_data) != AXE_SUCCEED)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get op data");
+ /* Attempt to cancel the task manually */
+ }
+done:
+ HG_Handler_start_output(handle, &status);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_cancel_op() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_create
+ *
+ * Purpose: Function shipper registered call for File Create.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_file_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ file_create_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (file_create_in_t *)H5MM_malloc(sizeof(file_create_in_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id, 0, NULL, 0, NULL,
+ H5VL_iod_server_file_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_file_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_open
+ *
+ * Purpose: Function shipper registered call for File Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_file_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ file_open_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (file_open_in_t *) H5MM_malloc(sizeof(file_open_in_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id, 0, NULL, 0, NULL,
+ H5VL_iod_server_file_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_file_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_file_close
+ *
+ * Purpose: Function shipper registered call for File Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_file_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ file_close_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (file_close_in_t *)
+ H5MM_malloc(sizeof(file_close_in_t))))
+ HGOTO_ERROR2(H5E_FILE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_barrier_task(engine, input->axe_info.axe_id,
+ H5VL_iod_server_file_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_FILE, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_file_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_create
+ *
+ * Purpose: Function shipper registered call for Attr Create.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_create_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_create_in_t *)
+ H5MM_malloc(sizeof(attr_create_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_open
+ *
+ * Purpose: Function shipper registered call for Attr Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_open_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_open_in_t *)
+ H5MM_malloc(sizeof(attr_open_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_read
+ *
+ * Purpose: Function shipper registered call for Attr Read.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_read(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_io_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_io_in_t *)
+ H5MM_malloc(sizeof(attr_io_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_read_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_write
+ *
+ * Purpose: Function shipper registered call for Attr Write.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_write(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_io_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_io_in_t *)
+ H5MM_malloc(sizeof(attr_io_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_write_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_exists
+ *
+ * Purpose: Function shipper registered call for Attr Exists.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_exists(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_op_in_t *)
+ H5MM_malloc(sizeof(attr_op_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_exists_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_rename
+ *
+ * Purpose: Function shipper registered call for Attr Rename.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_rename(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_rename_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_rename_in_t *)
+ H5MM_malloc(sizeof(attr_rename_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_rename_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_rename() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_remove
+ *
+ * Purpose: Function shipper registered call for Attr Remove.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_remove(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_op_in_t *)
+ H5MM_malloc(sizeof(attr_op_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_remove_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_attr_close
+ *
+ * Purpose: Function shipper registered call for Attr Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_attr_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ attr_close_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (attr_close_in_t *)
+ H5MM_malloc(sizeof(attr_close_in_t))))
+ HGOTO_ERROR2(H5E_ATTR, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_ATTR, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_attr_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_attr_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_create
+ *
+ * Purpose: Function shipper registered call for Group Create.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_group_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ group_create_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (group_create_in_t *)H5MM_malloc(sizeof(group_create_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_group_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_group_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_open
+ *
+ * Purpose: Function shipper registered call for Group Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_group_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ group_open_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (group_open_in_t *)H5MM_malloc(sizeof(group_open_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_group_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_group_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_group_close
+ *
+ * Purpose: Function shipper registered call for Group Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_group_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ group_close_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (group_close_in_t *)H5MM_malloc(sizeof(group_close_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_group_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_group_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_create
+ *
+ * Purpose: Function shipper registered call for Dset Create.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_create_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_create_in_t *)
+ H5MM_malloc(sizeof(dset_create_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_open
+ *
+ * Purpose: Function shipper registered call for Dset Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_open_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_open_in_t *)
+ H5MM_malloc(sizeof(dset_open_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_read
+ *
+ * Purpose: Function shipper registered call for Dset Read.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_read(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_io_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_io_in_t *)
+ H5MM_malloc(sizeof(dset_io_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_read_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_get_vl_size
+ *
+ * Purpose: Function shipper registered call for dset get VL buffer size.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_get_vl_size(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_io_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_io_in_t *)
+ H5MM_malloc(sizeof(dset_io_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_get_vl_size_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_get_vl_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_write
+ *
+ * Purpose: Function shipper registered call for Dset Write.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_write(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_io_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_io_in_t *)
+ H5MM_malloc(sizeof(dset_io_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_write_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_set_extent
+ *
+ * Purpose: Function shipper registered call for Dset Set_Extent.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_set_extent(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_set_extent_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_set_extent_in_t *)
+ H5MM_malloc(sizeof(dset_set_extent_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_set_extent_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_set_extent() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dset_close
+ *
+ * Purpose: Function shipper registered call for Dset Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * January, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dset_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dset_close_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dset_close_in_t *)
+ H5MM_malloc(sizeof(dset_close_in_t))))
+ HGOTO_ERROR2(H5E_DATASET, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATASET, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dset_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dset_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_commit
+ *
+ * Purpose: Function shipper registered call for Dtype Commit.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dtype_commit(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dtype_commit_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dtype_commit_in_t *)
+ H5MM_malloc(sizeof(dtype_commit_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dtype_commit_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dtype_commit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_open
+ *
+ * Purpose: Function shipper registered call for Dtype Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dtype_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dtype_open_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dtype_open_in_t *)
+ H5MM_malloc(sizeof(dtype_open_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dtype_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dtype_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_dtype_close
+ *
+ * Purpose: Function shipper registered call for Dtype Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * April, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_dtype_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ dtype_close_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (dtype_close_in_t *)
+ H5MM_malloc(sizeof(dtype_close_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_dtype_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_dtype_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_create
+ *
+ * Purpose: Function shipper registered call for Link Creation.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_create_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_create_in_t *)
+ H5MM_malloc(sizeof(link_create_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_move
+ *
+ * Purpose: Function shipper registered call for Link Move.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_move(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_move_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_move_in_t *)
+ H5MM_malloc(sizeof(link_move_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_move_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_move() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_iterate
+ *
+ * Purpose: Function shipper registered call for Link Iteration.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_iterate(hg_handle_t UNUSED handle)
+{
+ //op_data_t *op_data = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+#if 0
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_iterate_in_t *)
+ H5MM_malloc(sizeof(link_iterate_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+#endif
+
+ //done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_exists
+ *
+ * Purpose: Function shipper registered call for Link Existance.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_exists(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_op_in_t *)
+ H5MM_malloc(sizeof(link_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_exists_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_get_info
+ *
+ * Purpose: Function shipper registered call for Link get_info.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_get_info(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_op_in_t *)
+ H5MM_malloc(sizeof(link_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_get_info_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_get_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_get_val
+ *
+ * Purpose: Function shipper registered call for Link get_val.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_get_val(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_get_val_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_get_val_in_t *)
+ H5MM_malloc(sizeof(link_get_val_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_get_val_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_get_val() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_link_remove
+ *
+ * Purpose: Function shipper registered call for Link Removal.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_link_remove(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ link_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (link_op_in_t *)
+ H5MM_malloc(sizeof(link_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_link_remove_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_link_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_open_by_token
+ *
+ * Purpose: Function shipper registered call for Object Open by token.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_open_by_token(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_token_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_token_in_t *)
+ H5MM_malloc(sizeof(object_token_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_open_by_token_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_open_by_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_open
+ *
+ * Purpose: Function shipper registered call for Object Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_op_in_t *)
+ H5MM_malloc(sizeof(object_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_copy
+ *
+ * Purpose: Function shipper registered call for Object Copy.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_copy(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_copy_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_copy_in_t *)
+ H5MM_malloc(sizeof(object_copy_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_copy_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_visit
+ *
+ * Purpose: Function shipper registered call for Object Visit.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_visit(hg_handle_t UNUSED handle)
+{
+ //op_data_t *op_data = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ //done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_visit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_exists
+ *
+ * Purpose: Function shipper registered call for Object Existance.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_exists(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_op_in_t *)
+ H5MM_malloc(sizeof(object_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_exists_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_set_comment
+ *
+ * Purpose: Function shipper registered call for Set Comment.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_set_comment(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_set_comment_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_set_comment_in_t *)
+ H5MM_malloc(sizeof(object_set_comment_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_set_comment_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_set_comment() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_get_comment
+ *
+ * Purpose: Function shipper registered call for Get Comment.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_get_comment(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_get_comment_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_get_comment_in_t *)
+ H5MM_malloc(sizeof(object_get_comment_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_get_comment_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_get_comment() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_object_get_info
+ *
+ * Purpose: Function shipper registered call for Object get_info.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * May, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_object_get_info(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ object_op_in_t *input = NULL;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (object_op_in_t *)
+ H5MM_malloc(sizeof(object_op_in_t))))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_NOSPACE, HG_FAIL, "can't allocate input struct for decoding");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_object_get_info_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_object_get_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_create
+ *
+ * Purpose: Function shipper registered call for Map Create.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_create(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_create_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_create_in_t *)H5MM_malloc(sizeof(map_create_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_create_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_open
+ *
+ * Purpose: Function shipper registered call for Map Open.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_open(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_open_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_open_in_t *)H5MM_malloc(sizeof(map_open_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_open_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_set
+ *
+ * Purpose: Function shipper registered call for Map Set.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_set(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_set_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_set_in_t *)H5MM_malloc(sizeof(map_set_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_set_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_get
+ *
+ * Purpose: Function shipper registered call for Map Get.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_get(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_get_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_get_in_t *)H5MM_malloc(sizeof(map_get_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_get_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_get_count
+ *
+ * Purpose: Function shipper registered call for Map Get_Count.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_get_count(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_get_count_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_get_count_in_t *)H5MM_malloc(sizeof(map_get_count_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_get_count_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_get_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_exists
+ *
+ * Purpose: Function shipper registered call for Map Exists.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_exists(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_op_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_op_in_t *)H5MM_malloc(sizeof(map_op_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_exists_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_delete
+ *
+ * Purpose: Function shipper registered call for Map Delete.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_delete(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_op_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_op_in_t *)H5MM_malloc(sizeof(map_op_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_delete_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_map_close
+ *
+ * Purpose: Function shipper registered call for Map Close.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * July, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_map_close(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ map_close_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (map_close_in_t *)H5MM_malloc(sizeof(map_close_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_map_close_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_map_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_acquire
+ *
+ * Purpose: Function shipper registered call for Read Context Acquire.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_rcxt_acquire(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ rc_acquire_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (rc_acquire_in_t *)H5MM_malloc(sizeof(rc_acquire_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_rcxt_acquire_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_rcxt_acquire() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_release
+ *
+ * Purpose: Function shipper registered call for read context release.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_rcxt_release(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ rc_release_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (rc_release_in_t *)H5MM_malloc(sizeof(rc_release_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_rcxt_release_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_rcxt_release() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_persist
+ *
+ * Purpose: Function shipper registered call for read context persist.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_rcxt_persist(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ rc_persist_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (rc_persist_in_t *)H5MM_malloc(sizeof(rc_persist_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_rcxt_persist_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_rcxt_persist() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_snapshot
+ *
+ * Purpose: Function shipper registered call for read context snapshot.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_rcxt_snapshot(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ rc_snapshot_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (rc_snapshot_in_t *)H5MM_malloc(sizeof(rc_snapshot_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_rcxt_snapshot_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_rcxt_snapshot() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_start
+ *
+ * Purpose: Function shipper registered call for transaction start.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_trans_start(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ tr_start_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (tr_start_in_t *)H5MM_malloc(sizeof(tr_start_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_trans_start_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_trans_start() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_finish
+ *
+ * Purpose: Function shipper registered call for transaction finish.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_trans_finish(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ tr_finish_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (tr_finish_in_t *)H5MM_malloc(sizeof(tr_finish_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_trans_finish_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_trans_finish() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_set_dependency
+ *
+ * Purpose: Function shipper registered call for transaction set_dependency.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_trans_set_dependency(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ tr_set_depend_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (tr_set_depend_in_t *)H5MM_malloc(sizeof(tr_set_depend_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_trans_set_dependency_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_trans_set_dependency() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_skip
+ *
+ * Purpose: Function shipper registered call for transaction skip.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_trans_skip(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ tr_skip_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (tr_skip_in_t *)H5MM_malloc(sizeof(tr_skip_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_trans_skip_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_trans_skip() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_abort
+ *
+ * Purpose: Function shipper registered call for transaction abort.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_trans_abort(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ tr_abort_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (tr_abort_in_t *)H5MM_malloc(sizeof(tr_abort_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_trans_abort_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_trans_abort() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_prefetch
+ *
+ * Purpose: Function shipper registered call for object prefetch.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_prefetch(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ prefetch_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (prefetch_in_t *)H5MM_malloc(sizeof(prefetch_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_prefetch_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_prefetch() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_evict
+ *
+ * Purpose: Function shipper registered call for object evict.
+ * Inserts the real worker routine into the Async Engine.
+ *
+ * Return: Success: HG_SUCCESS
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5VL_iod_server_evict(hg_handle_t handle)
+{
+ op_data_t *op_data = NULL;
+ evict_in_t *input;
+ int ret_value = HG_SUCCESS;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (op_data = (op_data_t *)H5MM_malloc(sizeof(op_data_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(NULL == (input = (evict_in_t *)H5MM_malloc(sizeof(evict_in_t))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct");
+
+ if(HG_FAIL == HG_Handler_get_input(handle, input))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters");
+
+ if(NULL == engine)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started");
+
+ if(input->axe_info.count &&
+ H5VL__iod_server_finish_axe_tasks(engine, input->axe_info.start_range,
+ input->axe_info.count) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "Unable to cleanup AXE tasks");
+
+ op_data->hg_handle = handle;
+ op_data->input = (void *)input;
+
+ if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_info.axe_id,
+ input->axe_info.num_parents, input->axe_info.parent_axe_ids,
+ 0, NULL, H5VL_iod_server_evict_cb, op_data, NULL))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_server_evict() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_server.h b/src/H5VLiod_server.h
new file mode 100644
index 0000000..c9b1f28
--- /dev/null
+++ b/src/H5VLiod_server.h
@@ -0,0 +1,436 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5VL iod server module
+ */
+#ifndef _H5VLiod_server_H
+#define _H5VLiod_server_H
+
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Ppublic.h"
+#include "H5Spublic.h"
+#include "H5VLiod_common.h"
+
+#ifdef H5_HAVE_EFF
+
+/* Key names for Metadata stored in KV objects */
+#define H5VL_IOD_KEY_SOFT_LINK "soft_link_value"
+#define H5VL_IOD_KEY_DTYPE_SIZE "serialized_size"
+#define H5VL_IOD_KEY_KV_IDS_INDEX "kv_ids_index"
+#define H5VL_IOD_KEY_ARRAY_IDS_INDEX "array_ids_index"
+#define H5VL_IOD_KEY_BLOB_IDS_INDEX "blob_ids_index"
+#define H5VL_IOD_KEY_OBJ_COMMENT "object_comment"
+#define H5VL_IOD_KEY_OBJ_CPL "object_create_plist"
+#define H5VL_IOD_KEY_OBJ_LINK_COUNT "object_link_count"
+#define H5VL_IOD_KEY_OBJ_TYPE "object_type"
+#define H5VL_IOD_KEY_OBJ_DATATYPE "object_datatype"
+#define H5VL_IOD_KEY_OBJ_DATASPACE "object_dataspace"
+#define H5VL_IOD_KEY_MAP_KEY_TYPE "map_keytype"
+#define H5VL_IOD_KEY_MAP_VALUE_TYPE "map_valtype"
+
+/* Enum for metadata types stored in MD KV for HDF5->IOD objects */
+typedef enum H5VL_iod_metadata_t {
+ H5VL_IOD_PLIST, /*type ID for property lists */
+ H5VL_IOD_LINK_COUNT, /*type ID for link count */
+ H5VL_IOD_OBJECT_TYPE, /*type ID for object type */
+ H5VL_IOD_DATATYPE, /*type ID for datatypes */
+ H5VL_IOD_DATASPACE, /*type ID for dataspaces */
+ H5VL_IOD_LINK /*type ID for links */
+} H5VL_iod_metadata_t;
+
+/* the AXE op data strucutre stored with every operation */
+typedef struct op_data_t {
+ void *input;
+ void *output;
+ AXE_task_t axe_id;
+ hg_handle_t hg_handle;
+} op_data_t;
+
+/* the IOD scratch pad type */
+typedef iod_obj_id_t scratch_pad[4];
+
+/* the link value stored in KV stores */
+typedef struct H5VL_iod_link_t {
+ H5L_type_t link_type; /* The type of the link (Hard & Soft only suppoted for now) */
+ union {
+ iod_obj_id_t iod_id;
+ char *symbolic_name;
+ } u;
+ iod_obj_id_t iod_id; /* The ID of the object the link points to */
+} H5VL_iod_link_t;
+
+extern iod_obj_id_t ROOT_ID;
+extern int num_ions_g;
+extern int my_rank_g;
+extern na_addr_t *server_addr_g;
+extern char **server_loc_g;
+extern hg_id_t H5VL_EFF_OPEN_CONTAINER;
+extern hg_id_t H5VL_EFF_CLOSE_CONTAINER;
+extern hg_id_t H5VL_EFF_ANALYSIS_FARM;
+extern hg_id_t H5VL_EFF_ANALYSIS_FARM_TRANSFER;
+
+H5_DLL void EFF__mercury_register_callbacks(void);
+
+H5_DLL int H5VL_iod_server_analysis_execute(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_analysis_farm(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_analysis_transfer(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_container_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_container_close(hg_handle_t handle);
+
+H5_DLL int H5VL_iod_server_eff_init(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_eff_finalize(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_file_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_file_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_file_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_read(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_write(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_exists(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_rename(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_remove(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_attr_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_group_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_group_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_group_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_set(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_get(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_get_count(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_exists(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_delete(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_map_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_read(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_get_vl_size(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_write(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_set_extent(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dset_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dtype_commit(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dtype_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_dtype_close(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_cancel_op(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_create(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_move(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_exists(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_get_info(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_get_val(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_remove(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_link_iterate(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_open_by_token(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_open(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_copy(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_visit(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_exists(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_set_comment(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_get_comment(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_object_get_info(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_rcxt_acquire(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_rcxt_release(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_rcxt_persist(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_rcxt_snapshot(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_trans_start(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_trans_finish(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_trans_set_dependency(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_trans_skip(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_trans_abort(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_prefetch(hg_handle_t handle);
+H5_DLL int H5VL_iod_server_evict(hg_handle_t handle);
+
+H5_DLL void H5VL_iod_server_analysis_execute_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *_op_data);
+H5_DLL void H5VL_iod_server_analysis_farm_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *_op_data);
+H5_DLL void H5VL_iod_server_analysis_transfer_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *_op_data);
+
+H5_DLL void H5VL_iod_server_file_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_file_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_file_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_read_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_write_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_exists_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_rename_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_remove_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_attr_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_group_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_group_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_group_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_set_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_get_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_get_count_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_exists_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_delete_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_map_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_read_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_get_vl_size_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_write_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_set_extent_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dset_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dtype_commit_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dtype_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_dtype_close_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_create_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_move_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_exists_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_get_info_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_get_val_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_link_remove_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+
+H5_DLL void H5VL_iod_server_object_open_by_token_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *_op_data);
+H5_DLL void H5VL_iod_server_object_open_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_object_copy_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_object_exists_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_object_set_comment_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_object_get_comment_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_object_get_info_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+
+H5_DLL void H5VL_iod_server_rcxt_acquire_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_rcxt_release_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_rcxt_persist_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_rcxt_snapshot_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_trans_start_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_trans_finish_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_trans_set_dependency_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_trans_skip_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_trans_abort_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_prefetch_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+H5_DLL void H5VL_iod_server_evict_cb(AXE_engine_t axe_engine,
+ size_t num_n_parents, AXE_task_t n_parents[],
+ size_t num_s_parents, AXE_task_t s_parents[],
+ void *op_data);
+
+/* Helper routines used several times in different places */
+H5_DLL herr_t H5VL_iod_server_traverse(iod_handle_t coh, iod_obj_id_t loc_id, iod_handles_t loc_handle,
+ const char *path, iod_trans_id_t wtid, iod_trans_id_t rtid,
+ hbool_t create_interm_grps, uint32_t cs_scope,
+ char **last_comp, iod_obj_id_t *iod_id, iod_handles_t *iod_oh);
+H5_DLL herr_t H5VL_iod_server_open_path(iod_handle_t coh, iod_obj_id_t loc_id,
+ iod_handles_t loc_handle, const char *path,
+ iod_trans_id_t tid, uint32_t cs_scope,
+ /*out*/iod_obj_id_t *iod_id, /*out*/iod_handles_t *iod_oh);
+H5_DLL herr_t H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs);
+H5_DLL herr_t H5VL_iod_insert_plist(iod_handle_t oh, iod_trans_id_t tid, hid_t plist_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_link_count(iod_handle_t oh, iod_trans_id_t tid, uint64_t count,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_object_type(iod_handle_t oh, iod_trans_id_t tid, H5I_type_t obj_type,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_datatype(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_datatype_with_key(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id,
+ const char *key, uint32_t cs_scope,
+ iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_dataspace(iod_handle_t oh, iod_trans_id_t tid, hid_t space_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event);
+H5_DLL herr_t H5VL_iod_insert_new_link(iod_handle_t oh, iod_trans_id_t tid, const char *link_name,
+ H5L_type_t link_type, const void *link_val,
+ uint32_t cs_scope, iod_hint_list_t *hints,
+ iod_event_t *event);
+H5_DLL herr_t H5VL_iod_get_metadata(iod_handle_t oh, iod_trans_id_t tid, H5VL_iod_metadata_t md_type,
+ const char *key, uint32_t cs_scope, iod_event_t *event, void *ret);
+H5_DLL herr_t H5VL__iod_server_adjust_buffer(hid_t from_type_id, hid_t to_type_id, size_t nelmts,
+ hid_t dxpl_id, size_t size, void **buf,
+ hbool_t *is_vl_data, size_t *_buf_size);
+H5_DLL herr_t H5VL_iod_verify_scratch_pad(scratch_pad *sp, iod_checksum_t iod_cs);
+H5_DLL herr_t H5VL_iod_verify_kv_pair(void *key, iod_size_t key_size, void *value, iod_size_t val_size,
+ iod_checksum_t *iod_cs);
+H5_DLL herr_t H5VL__iod_server_final_io(iod_handle_t iod_oh, hid_t space_id, size_t elmt_size,
+ hbool_t write_op, void *buf, size_t buf_size,
+ iod_checksum_t cs, uint32_t cs_scope, iod_trans_id_t tid);
+
+#endif /* H5_HAVE_EFF */
+#endif /* _H5VLiod_server_H */
diff --git a/src/H5VLiod_trans.c b/src/H5VLiod_trans.c
new file mode 100644
index 0000000..1dd41cb
--- /dev/null
+++ b/src/H5VLiod_trans.c
@@ -0,0 +1,773 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5VLiod_server.h"
+#include "H5RCpublic.h"
+#include "H5TRpublic.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * July, 2013
+ *
+ * Purpose: The IOD plugin server side transaction and read context routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_acquire_cb
+ *
+ * Purpose: Acquire a read context of a container using a version number.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_rcxt_acquire_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ rc_acquire_in_t *input = (rc_acquire_in_t *)op_data->input;
+ rc_acquire_out_t output;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t c_version = input->c_version;
+ iod_trans_id_t acquired_version;
+ hid_t rcapl_id;
+ iod_ret_t ret;
+ H5RC_request_t acquire_req;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(H5P_DEFAULT == input->rcapl_id)
+ input->rcapl_id = H5Pcopy(H5P_RC_ACQUIRE_DEFAULT);
+ rcapl_id = input->rcapl_id;
+
+ if(H5Pget_rcapl_version_request(rcapl_id, &acquire_req) < 0) {
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTSET,FAIL, "can't get acquire request property");
+ }
+
+ switch(acquire_req) {
+ case H5RC_EXACT:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Exact Acquire Read Context %"PRIu64"\n", input->c_version);
+#endif
+ if((ret = iod_trans_start(coh, &c_version, NULL, 0, IOD_TRANS_R, NULL)) < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't acquire read context");
+ }
+ acquired_version = c_version;
+ break;
+ case H5RC_LAST:
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Acquire LAST Read Context\n");
+#endif
+ c_version = IOD_TID_UNKNOWN;
+ if(iod_trans_start(coh, &c_version, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't acquire read context");
+ acquired_version = c_version;
+ break;
+ case H5RC_NEXT:
+ {
+ iod_cont_trans_stat_t *tids;
+ uint64_t u;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Next Acquire Read Context %"PRIu64"\n", input->c_version);
+#endif
+ if(iod_query_cont_trans_stat(coh, &tids, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get container tids status");
+
+ acquired_version = IOD_TID_UNKNOWN;
+
+ for(u=c_version; u<tids->latest_rdable ; u++) {
+ if(iod_trans_start(coh, &u, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ continue;
+ acquired_version = u;
+ break;
+ }
+
+ if(IOD_TID_UNKNOWN == acquired_version) {
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL,
+ "can't get a read version");
+ }
+
+ if(iod_free_cont_trans_stat(coh, tids) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free container transaction status object");
+ break;
+ }
+ case H5RC_PREV:
+ {
+ iod_cont_trans_stat_t *tids;
+ uint64_t u;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Next Acquire Read Context %"PRIu64"\n", input->c_version);
+#endif
+ if(iod_query_cont_trans_stat(coh, &tids, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't get container tids status");
+
+ if(c_version >= tids->latest_rdable) {
+ acquired_version = tids->latest_rdable;
+ if(iod_trans_start(coh, &acquired_version, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't acquire read context");
+ break;
+ }
+
+ acquired_version = IOD_TID_UNKNOWN;
+ u=c_version;
+
+ for(u=c_version; u>0; u--) {
+ if(iod_trans_start(coh, &u, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ continue;
+ acquired_version = u;
+ break;
+ }
+
+ if(IOD_TID_UNKNOWN == acquired_version) {
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL,
+ "can't get a read version");
+ }
+
+ if(iod_free_cont_trans_stat(coh, tids) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't free container transaction status object");
+
+ break;
+ }
+ default:
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTSET, FAIL, "invalid acquire request");
+ }
+
+ output.c_version = acquired_version;
+ output.ret = ret_value;
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Acquire Read Context. Acquired %"PRIu64"\n", output.c_version);
+#endif
+
+ HG_Handler_start_output(op_data->hg_handle, &output);
+
+done:
+ /* return an UNDEFINED oh to the client if the operation failed */
+ if(ret_value < 0) {
+ fprintf(stderr, "Failed to Acquire Read context\n");
+ output.ret = FAIL;
+ output.c_version = c_version;
+ HG_Handler_start_output(op_data->hg_handle, &output);
+ }
+
+ input = (rc_acquire_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_rcxt_acquire_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_release_cb
+ *
+ * Purpose: Release a read context of a container using a version number.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_rcxt_release_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ rc_release_in_t *input = (rc_release_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Release Read Context %"PRIu64"\n", input->c_version);
+#endif
+
+ if(iod_trans_finish(coh, input->c_version, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't release Read Context");
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Release Read context\n");
+
+ input = (rc_release_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_rcxt_release_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_persist_cb
+ *
+ * Purpose: Persist a read context of a container using a version number.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_rcxt_persist_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ rc_persist_in_t *input = (rc_persist_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Persist Read Context %"PRIu64"\n", input->c_version);
+#endif
+
+ if(iod_trans_persist(coh, input->c_version, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't persist Read Context");
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Persist Read context\n");
+
+ input = (rc_persist_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_rcxt_persist_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_rcxt_snapshot_cb
+ *
+ * Purpose: Snapshot a read context of a container using a version number.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_rcxt_snapshot_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ rc_snapshot_in_t *input = (rc_snapshot_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t tid = input->c_version;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Snapshot %s with Read Context %"PRIu64"\n", input->snapshot_name, input->c_version);
+#endif
+
+ /* MSC - can only snapshot latest version */
+ if(iod_container_snapshot(coh, tid, input->snapshot_name, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't snapshot Read Context");
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Snapshot Read context\n");
+
+ input = (rc_snapshot_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_rcxt_snapshot_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_start_cb
+ *
+ * Purpose: Start a transaction on a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_trans_start_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ tr_start_in_t *input = (tr_start_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ hid_t trspl_id;
+ iod_trans_id_t trans_num = input->trans_num;
+ unsigned num_peers; /* the number of peers starting this transaction */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Transaction Start %"PRIu64"\n", input->trans_num);
+#endif
+
+ if(H5P_DEFAULT == input->trspl_id)
+ input->trspl_id = H5Pcopy(H5P_TR_START_DEFAULT);
+ trspl_id = input->trspl_id;
+
+ if(H5Pget_trspl_num_peers(trspl_id, &num_peers) < 0)
+ HGOTO_ERROR2(H5E_PLIST, H5E_CANTGET, FAIL, "can't get acquire request property");
+
+ if(iod_trans_start(coh, &trans_num, NULL, num_peers, IOD_TRANS_W, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't start transaction");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Transaction Start\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Start Transaction\n");
+
+ input = (tr_start_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_trans_start_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_finish_cb
+ *
+ * Purpose: Finish a transaction on a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_trans_finish_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ tr_finish_in_t *input = (tr_finish_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ uint32_t cs_scope = input->cs_scope;
+ //hid_t trfpl_id;
+ iod_trans_id_t trans_num = input->trans_num;
+ hbool_t acquire = input->acquire;
+ uint32_t client_rank = input->client_rank;
+ iod_obj_id_t oidkv_id = input->oidkv_id;
+ iod_handle_t oidkv_oh;
+ uint64_t oid_index[3];
+ iod_kv_t kv;
+ iod_ret_t ret;
+ int step = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Transaction Finish %"PRIu64"\n", trans_num);
+#endif
+
+ IOD_OBJID_SETTYPE(oidkv_id, IOD_OBJ_KV)
+ IOD_OBJID_SETOWNER_APP(oidkv_id)
+
+ oid_index[0] = input->kv_oid_index;
+ oid_index[1] = input->array_oid_index;
+ oid_index[2] = input->blob_oid_index;
+
+ ret = iod_obj_open_write(coh, oidkv_id, trans_num, NULL, &oidkv_oh, NULL);
+ if(ret != 0)
+ HGOTO_ERROR_IOD(ret, FAIL, "can't open oid KV");
+
+ step ++;
+
+ kv.value = &oid_index;
+ kv.value_len = sizeof(iod_obj_id_t) * 3;
+ kv.key = &client_rank;
+ kv.key_len = sizeof(uint32_t);
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+ if (iod_kv_set(oidkv_oh, trans_num, NULL, &kv, cs, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oidkv_oh, trans_num, NULL, &kv, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in oid KV");
+ }
+
+ if(iod_obj_close(oidkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object handle");
+
+ step --;
+
+ /* Finish the transaction */
+ if(iod_trans_finish(coh, trans_num, NULL, 0, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't finish transaction");
+
+ /* if the flag is true, acquire a read context on the finished transaction */
+ if(TRUE == acquire) {
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Transaction Acquire after Finish %"PRIu64"\n", trans_num);
+#endif
+
+ if(iod_trans_start(coh, &trans_num, NULL, 0, IOD_TRANS_R, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't acquire read context");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Transaction Finish\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Finish Transaction\n");
+
+ if(step == 1) {
+ iod_obj_close(oidkv_oh, NULL, NULL);
+ }
+
+ input = (tr_finish_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_trans_finish_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_set_dependency_cb
+ *
+ * Purpose: Set Dependency between 2 transactions on a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_trans_set_dependency_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ tr_set_depend_in_t *input = (tr_set_depend_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_depend_desc_t depends;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Transaction Set_Dependency %"PRIu64" on %"PRIu64"\n",
+ input->child_trans_num, input->parent_trans_num);
+#endif
+
+ /* MSC - set depends */
+
+ //if(iod_trans_depend(coh, depends, NULL) < 0)
+ //HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set dependency between transactions");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Transaction Set_Dependency\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Set_Dependency between Transactions\n");
+
+ input = (tr_set_depend_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_trans_set_dependency_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_skip_cb
+ *
+ * Purpose: Skip a number of transactions on a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_trans_skip_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ tr_skip_in_t *input = (tr_skip_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t start_trans_num = input->start_trans_num;
+ uint64_t count = input->count;
+ iod_trans_range_desc_t skip_ranges;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Transaction Skip %"PRIu64" starting at %"PRIu64"\n", count, start_trans_num);
+#endif
+
+ /* MSC - set skip ranges */
+ skip_ranges.n_range = 1;
+ //if(iod_trans_skip(coh, skip_ranges, NULL) < 0)
+ //HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't skip transactions");
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Transaction Skip\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Skip Transaction\n");
+
+ input = (tr_skip_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_trans_skip_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_trans_abort_cb
+ *
+ * Purpose: Abort a transaction on a container.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_trans_abort_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ tr_abort_in_t *input = (tr_abort_in_t *)op_data->input;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t trans_num = input->trans_num;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Aborting Transaction %"PRIu64"\n", input->trans_num);
+#endif
+
+ ret = iod_trans_finish(coh, trans_num, NULL, IOD_TRANS_ABORT_DEPENDENT, NULL);
+ if(ret == -IOD_EC_TRANS_DISCARDED)
+ fprintf(stderr, "Transaction %"PRIu64" already discarded\n", input->trans_num);
+ else if(ret < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTSET, FAIL, "can't abort transaction");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Transaction Abort\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Abort Transaction\n");
+
+ input = (tr_abort_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_trans_abort_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_prefetch_cb
+ *
+ * Purpose: prefetch an object from central storage to BB.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_prefetch_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ prefetch_in_t *input = (prefetch_in_t *)op_data->input;
+ //iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t tid = input->rcxt_num;
+ iod_handles_t iod_oh = input->iod_oh; /* object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* OID */
+ //H5I_type_t obj_type = input->obj_type;
+ //hid_t apl_id = input->apl_id;
+ iod_trans_id_t replica_id;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Prefetch Object (OID %"PRIx64" OH %"PRIu64") at Version %"PRIu64"\n",
+ iod_id, iod_oh.rd_oh.cookie, tid);
+#endif
+
+ ret = iod_obj_fetch(iod_oh.rd_oh, tid, NULL, NULL, NULL, &replica_id, NULL);
+ if(ret != 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't prefetch object");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Prefetch\n");
+#endif
+
+done:
+ if(SUCCEED != ret_value)
+ replica_id = 0;
+
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &replica_id))
+ fprintf(stderr, "Failed to Prefetch Object\n");
+
+ input = (prefetch_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_prefetch_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_evict_cb
+ *
+ * Purpose: evicts an object from BB.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * February 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_evict_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ evict_in_t *input = (evict_in_t *)op_data->input;
+ //iod_handle_t coh = input->coh; /* the container handle */
+ iod_trans_id_t tid = input->rcxt_num;
+ iod_handles_t iod_oh = input->iod_oh; /* object handle */
+ iod_obj_id_t iod_id = input->iod_id; /* OID */
+ //H5I_type_t obj_type = input->obj_type;
+ //hid_t apl_id = input->apl_id;
+ iod_trans_id_t replica_id = input->replica_id;
+ iod_ret_t ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(replica_id) {
+ fprintf(stderr, "Evict Object (OID %"PRIx64" OH %"PRIu64") replica tag %"PRIx64"\n",
+ iod_id, iod_oh.rd_oh.cookie, replica_id);
+ ret = iod_obj_purge(iod_oh.rd_oh, replica_id, NULL, NULL);
+ }
+ else {
+ fprintf(stderr, "Evict Object (OID %"PRIx64" OH %"PRIu64") at Version %"PRIu64"\n",
+ iod_id, iod_oh.rd_oh.cookie, tid);
+ ret = iod_obj_purge(iod_oh.rd_oh, tid, NULL, NULL);
+ }
+
+ if(ret < 0) {
+ fprintf(stderr, "%d (%s).\n", ret, strerror(-ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "can't evict object");
+ }
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Done with Evict\n");
+#endif
+
+done:
+ if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &ret_value))
+ fprintf(stderr, "Failed to Evict Object\n");
+
+ input = (evict_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_evict_cb() */
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_util.c b/src/H5VLiod_util.c
new file mode 100644
index 0000000..c577ecb
--- /dev/null
+++ b/src/H5VLiod_util.c
@@ -0,0 +1,1288 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+#include "H5Gpkg.h" /* Groups */
+#include "H5Sprivate.h" /* Dataspaces */
+#include "H5WBprivate.h" /* Wrapped Buffers */
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * February, 2013
+ *
+ * Purpose: The IOD plugin server utility routines.
+ */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_traverse
+ *
+ * Purpose:
+ * Function to Traverse the path in IOD KV objects given the
+ * starting location ID, object handle, and path name. This walks
+ * through the IOD KV objects to get to the last component in the
+ * path. The last component is not opened. Usually this is called when
+ * creating an object. The Function returns the iod ID and object
+ * handle of the before to last component, and the last component
+ * string, if the user requests it.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_server_traverse(iod_handle_t coh, iod_obj_id_t loc_id, iod_handles_t loc_handle,
+ const char *path, iod_trans_id_t wtid, iod_trans_id_t rtid,
+ hbool_t create_interm_grps, uint32_t cs_scope,
+ /* out */char **last_comp, /* out */iod_obj_id_t *iod_id,
+ /* out */iod_handles_t *iod_oh)
+{
+ char comp_buf[1024]; /* Temporary buffer for path components */
+ char *comp; /* Pointer to buffer for path components */
+ H5WB_t *wb = NULL; /* Wrapped buffer for temporary buffer */
+ size_t nchars; /* component name length */
+ iod_handles_t cur_oh;
+ iod_handle_t prev_oh;
+ iod_obj_id_t cur_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Creating intermediate groups is not supported for now */
+ assert(FALSE == create_interm_grps);
+
+ cur_oh.rd_oh.cookie = loc_handle.rd_oh.cookie;
+ cur_oh.wr_oh.cookie = loc_handle.wr_oh.cookie;
+ cur_id = loc_id;
+
+ /* open the current group */
+ if(cur_oh.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, loc_id, wtid, NULL, &cur_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ }
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(comp_buf, sizeof(comp_buf))))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+ /* Get a pointer to a buffer that's large enough */
+ if(NULL == (comp = (char *)H5WB_actual(wb, (HDstrlen(path) + 1))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Traverse the path */
+ while((path = H5G__component(path, &nchars)) && *path) {
+ const char *s; /* Temporary string pointer */
+ iod_size_t kv_size;
+ H5VL_iod_link_t value;
+
+ /* Copy the component path into a null-terminated buffer. */
+ HDmemcpy(comp, path, nchars);
+ comp[nchars] = '\0';
+
+ /*
+ * The special path `.' is a no-op.
+ */
+ if('.' == comp[0] && !comp[1]) {
+ path += nchars;
+ continue;
+ } /* end if */
+
+ /* Check if this is the last component of the path */
+ if(!((s = H5G__component(path + nchars, NULL)) && *s)) {
+ if(last_comp) {
+ *last_comp = HDstrdup(comp);
+ }
+ break;
+ }
+
+ kv_size = sizeof(H5VL_iod_link_t);
+
+ prev_oh.cookie = cur_oh.rd_oh.cookie;
+
+ /* lookup next object in the current group */
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ comp, cs_scope, NULL, &value) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+
+ /* if this a soft link, traverse the link value if the ID is undefined */
+ if(H5L_TYPE_SOFT == value.link_type) {
+ if('/' == *value.u.symbolic_name) {
+ cur_id = ROOT_ID;
+ }
+
+ /* Traverse Path and open the target object */
+ if(H5VL_iod_server_open_path(coh, cur_id, cur_oh, value.u.symbolic_name,
+ rtid, cs_scope, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ free(value.u.symbolic_name);
+ }
+ else
+ cur_id = value.u.iod_id;
+
+ /* Close previous read handle unless it is the original one */
+ if(loc_handle.rd_oh.cookie != prev_oh.cookie) {
+ if(iod_obj_close(prev_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close current object handle");
+ }
+
+ /* open the current group */
+ if (iod_obj_open_read(coh, cur_id, rtid, NULL, &cur_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ /* Advance to next component in string */
+ path += nchars;
+ } /* end while */
+
+ /* Release temporary component buffer */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't release wrapped buffer");
+
+ *iod_id = cur_id;
+ (*iod_oh).rd_oh.cookie = cur_oh.rd_oh.cookie;
+
+ if(cur_id != loc_id ||
+ loc_handle.wr_oh.cookie == IOD_OH_UNDEFINED) {
+ /* open a write handle on the ID. */
+ if (iod_obj_open_write(coh, cur_id, wtid, NULL, &cur_oh.wr_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ }
+
+ (*iod_oh).wr_oh.cookie = cur_oh.wr_oh.cookie;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_open_path
+ *
+ * Purpose: Function to Traverse the path in IOD KV objects given the
+ * starting location ID, object handle, and path name. This walks
+ * through the IOD KV objects to get to the last component in the path
+ * and opens the last component for read only, i.e. does not open the
+ * wr_oh, but will set it to undefined. Usually this is called when
+ * opening an object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_server_open_path(iod_handle_t coh, iod_obj_id_t loc_id, iod_handles_t loc_handle,
+ const char *path, iod_trans_id_t rtid, uint32_t cs_scope,
+ /*out*/iod_obj_id_t *iod_id, /*out*/iod_handles_t *iod_oh)
+{
+ char comp_buf[1024]; /* Temporary buffer for path components */
+ char *comp; /* Pointer to buffer for path components */
+ H5WB_t *wb = NULL; /* Wrapped buffer for temporary buffer */
+ size_t nchars; /* component name length */
+ iod_handles_t cur_oh;
+ iod_handle_t prev_oh;
+ iod_obj_id_t cur_id;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ cur_oh.rd_oh.cookie = loc_handle.rd_oh.cookie;
+ cur_oh.wr_oh.cookie = loc_handle.wr_oh.cookie;
+ cur_id = loc_id;
+
+ if(cur_oh.rd_oh.cookie == IOD_OH_UNDEFINED) {
+ /* open the current group */
+ if (iod_obj_open_read(coh, loc_id, rtid, NULL, &cur_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open start location");
+ }
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(comp_buf, sizeof(comp_buf))))
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
+ /* Get a pointer to a buffer that's large enough */
+ if(NULL == (comp = (char *)H5WB_actual(wb, (HDstrlen(path) + 1))))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
+
+ /* Traverse the path */
+ while((path = H5G__component(path, &nchars)) && *path) {
+ iod_size_t kv_size;
+ H5VL_iod_link_t value;
+
+ /* Copy the component path into a null-terminated buffer. */
+ HDmemcpy(comp, path, nchars);
+ comp[nchars] = '\0';
+
+ /*
+ * The special path `.' is a no-op.
+ */
+ if('.' == comp[0] && !comp[1]) {
+ path += nchars;
+ continue;
+ } /* end if */
+
+ kv_size = sizeof(H5VL_iod_link_t);
+
+ prev_oh.cookie = cur_oh.rd_oh.cookie;
+
+ /* lookup next object in the current group */
+ if(H5VL_iod_get_metadata(cur_oh.rd_oh, rtid, H5VL_IOD_LINK,
+ comp, cs_scope, NULL, &value) < 0) {
+ /* Close previous handle unless it is the original one */
+ if(loc_handle.rd_oh.cookie != prev_oh.cookie &&
+ iod_obj_close(prev_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close current object handle");
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link value");
+ }
+
+ /* if this a soft link, traverse the link value if the ID is undefined */
+ if(H5L_TYPE_SOFT == value.link_type) {
+ if('/' == *value.u.symbolic_name) {
+ cur_id = ROOT_ID;
+ }
+
+ /* Traverse Path and open the target object */
+ if(H5VL_iod_server_open_path(coh, cur_id, cur_oh, value.u.symbolic_name,
+ rtid, cs_scope, &cur_id, &cur_oh) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't open object");
+
+ free(value.u.symbolic_name);
+ }
+ else
+ cur_id = value.u.iod_id;
+
+ /* Close previous handle unless it is the original one */
+ if(loc_handle.rd_oh.cookie != prev_oh.cookie &&
+ iod_obj_close(prev_oh, NULL, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't close current object handle");
+
+ /* open the current group */
+ if (iod_obj_open_read(coh, cur_id, rtid, NULL, &cur_oh.rd_oh, NULL) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current object");
+
+ /* Advance to next component in string */
+ path += nchars;
+ } /* end while */
+
+ /* Release temporary component buffer */
+ if(wb && H5WB_unwrap(wb) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't release wrapped buffer");
+
+ *iod_id = cur_id;
+ (*iod_oh).rd_oh.cookie = cur_oh.rd_oh.cookie;
+ (*iod_oh).wr_oh.cookie = IOD_OH_UNDEFINED;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_file_desc
+ *
+ * Purpose:
+ * Function to generate IOD hyperslab objects from HDF5
+ * dataspace selections. If hslabs is NULL, a count of the number of
+ * hslabs needed is returned in count.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs)
+{
+ hssize_t num_descriptors = 0, n;
+ int ndims = 0, i;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the rank of this dataspace */
+ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0)
+ HGOTO_ERROR2(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion");
+
+ switch(H5Sget_select_type(space_id)) {
+ case H5S_SEL_NONE:
+ /* nothing selected */
+ num_descriptors = 0;
+ HGOTO_DONE(SUCCEED);
+ case H5S_SEL_ALL:
+ /* The entire dataspace is selected, 1 large iod hyperslab is needed */
+ num_descriptors = 1;
+
+ if(NULL != hslabs) {
+ hsize_t dims[H5S_MAX_RANK];
+
+ /* get the dimensions sizes of the dataspace */
+ if(H5Sget_simple_extent_dims(space_id, dims, NULL) < 0)
+ HGOTO_ERROR2(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion sizes");
+ /* populate the hyperslab */
+ for(i=0 ; i<ndims ; i++) {
+ hslabs[0].start[i] = 0;
+ hslabs[0].block[i] = dims[i];
+ hslabs[0].stride[i] = dims[i];
+ hslabs[0].count[i] = 1;
+ }
+ }
+ break;
+ case H5S_SEL_POINTS:
+ {
+ /* we need a hyperslab element for each point */
+ if((num_descriptors = H5Sget_select_elem_npoints(space_id)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "invalid point selection");
+
+ if(NULL != hslabs) {
+ hsize_t *points = NULL;
+ size_t point_count = 0;
+
+ point_count = ndims * num_descriptors * sizeof(hsize_t);
+
+ if(NULL == (points = (hsize_t *)malloc(point_count)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for points coords");
+
+ if(H5Sget_select_elem_pointlist(space_id, (hsize_t)0,
+ (hsize_t)num_descriptors, points) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "Failed to retrieve point coordinates");
+
+ /* populate the hyperslab */
+ for(n=0 ; n<num_descriptors ; n++) {
+ hsize_t *cur_ptr = points; /* temp pointer into points array */
+
+ /* adjust the current pointer to the current point */
+ cur_ptr += n*ndims;
+ for(i=0 ; i<ndims ; i++) {
+ hslabs[n].start[i] = *(cur_ptr+i);
+ hslabs[n].count[i] = 1;
+ hslabs[n].block[i] = 1;
+ hslabs[n].stride[i] = hslabs[n].block[i];
+ }
+ }
+
+ free(points);
+ }
+ break;
+ }
+ case H5S_SEL_HYPERSLABS:
+ {
+ /* if the selection is a regular hyperslab
+ selection, only 1 iod hyperslab object is
+ needed */
+ if(H5Sselect_is_regular(space_id)) {
+ num_descriptors = 1;
+
+ if(NULL != hslabs) {
+ if(H5Sget_reg_hyperslab_params(space_id,
+ hslabs[0].start,
+ hslabs[0].stride,
+ hslabs[0].count,
+ hslabs[0].block) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "Failed to retrieve hyperslab selection");
+ for(i=0 ; i<ndims ; i++) {
+ hslabs[0].stride[i] = hslabs[0].block[i] * hslabs[0].stride[i];
+ }
+ }
+ }
+ /* Otherwise populate the hslabs by getting every block */
+ else {
+ if((num_descriptors = H5Sget_select_hyper_nblocks(space_id)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "invalid hyperslab selection");
+
+ if(NULL != hslabs) {
+ hsize_t *blocks = NULL;
+ size_t block_count = 0;
+
+ block_count = ndims * (size_t)num_descriptors * sizeof(hsize_t) * 2;
+
+ if(NULL == (blocks = (hsize_t *)malloc(block_count)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for points coords");
+
+ fprintf(stderr, "block count = %zu\n", block_count);
+
+ if(H5Sget_select_hyper_blocklist(space_id, (hsize_t)0,
+ (hsize_t)num_descriptors, blocks) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTGET, FAIL, "Failed to retrieve point coordinates");
+
+ /* populate the hyperslab */
+ for(n=0 ; n<num_descriptors ; n++) {
+ hsize_t *cur_ptr = blocks; /* temp pointer into blocks array */
+
+ /* adjust the current pointer to the current block */
+ cur_ptr += n*ndims*2;
+ for(i=0 ; i<ndims ; i++) {
+ hslabs[n].start[i] = *(cur_ptr+i);
+ hslabs[n].count[i] = 1;
+ hslabs[n].block[i] = *(cur_ptr+ndims+i) - hslabs[n].start[i];
+ hslabs[n].stride[i] = hslabs[n].block[i];
+ }
+ }
+
+ free(blocks);
+ }
+ }
+ break;
+ }
+ case H5S_SEL_ERROR:
+ case H5S_SEL_N:
+ default:
+ HGOTO_ERROR2(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "Invalid Selection type");
+ }
+
+ *count = num_descriptors;
+
+ done:
+ FUNC_LEAVE_NOAPI(ret_value)
+ }
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_plist
+ *
+ * Purpose: Function to insert a creation property list in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_plist(iod_handle_t oh, iod_trans_id_t tid, hid_t plist_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event)
+{
+ char *key = NULL;
+ void *value = NULL;
+ iod_kv_t kv;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* insert group creation properties in Metadata KV */
+ key = strdup(H5VL_IOD_KEY_OBJ_CPL);
+
+ /* determine the buffer size needed to store the encoded plist */
+ if(H5Pencode(plist_id, NULL, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode plist");
+ if(NULL == (value = malloc (buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate plist buffer");
+ /* encode plist */
+ if(H5Pencode(plist_id, value, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode plist");
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = value;
+ kv.value_len = (iod_size_t)buf_size;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "PLIST Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(key) {
+ free(key);
+ key = NULL;
+ }
+ if(value) {
+ free(value);
+ value = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_link_count
+ *
+ * Purpose: Function to insert the link count in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_link_count(iod_handle_t oh, iod_trans_id_t tid, uint64_t count,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event)
+{
+ char *key = NULL;
+ iod_kv_t kv;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ key = strdup(H5VL_IOD_KEY_OBJ_LINK_COUNT);
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = &count;
+ kv.value_len = sizeof(uint64_t);
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Link Count Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(key) {
+ free(key);
+ key = NULL;
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_object_type
+ *
+ * Purpose: Function to insert the object type in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_object_type(iod_handle_t oh, iod_trans_id_t tid, H5I_type_t obj_type,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event)
+{
+ char *key = NULL;
+ iod_kv_t kv;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ key = strdup(H5VL_IOD_KEY_OBJ_TYPE);
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = &obj_type;
+ kv.value_len = sizeof(int32_t);
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Object Type Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(key) {
+ free(key);
+ key = NULL;
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_datatype
+ *
+ * Purpose: Function to insert a datatype in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_datatype(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event)
+{
+ char *key = NULL;
+ void *value = NULL;
+ iod_kv_t kv;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* insert group creation properties in Metadata KV */
+ key = strdup(H5VL_IOD_KEY_OBJ_DATATYPE);
+
+ /* determine the buffer size needed to store the encoded type */
+ if(H5Tencode(type_id, NULL, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type");
+ if(NULL == (value = malloc (buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer");
+ /* encode type */
+ if(H5Tencode(type_id, value, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type");
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = value;
+ kv.value_len = (iod_size_t)buf_size;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Datatype Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(key) {
+ free(key);
+ key = NULL;
+ }
+ if(value) {
+ free(value);
+ value = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_datatype_with_key
+ *
+ * Purpose: Function to insert a datatype in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_datatype_with_key(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id,
+ const char *key, uint32_t cs_scope, iod_hint_list_t *hints,
+ iod_event_t *event)
+{
+ void *value = NULL;
+ iod_kv_t kv;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* determine the buffer size needed to store the encoded type */
+ if(H5Tencode(type_id, NULL, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type");
+ if(NULL == (value = malloc (buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer");
+ /* encode type */
+ if(H5Tencode(type_id, value, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type");
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = value;
+ kv.value_len = (iod_size_t)buf_size;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Map Datatype Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(value) {
+ free(value);
+ value = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_dataspace
+ *
+ * Purpose: Function to insert a dataspace in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_dataspace(iod_handle_t oh, iod_trans_id_t tid, hid_t space_id,
+ uint32_t cs_scope, iod_hint_list_t *hints, iod_event_t *event)
+{
+ char *key = NULL;
+ void *value = NULL;
+ iod_kv_t kv;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* insert group creation properties in Metadata KV */
+ key = strdup(H5VL_IOD_KEY_OBJ_DATASPACE);
+
+ /* determine the buffer size needed to store the encoded space */
+ if(H5Sencode(space_id, NULL, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode space");
+ if(NULL == (value = malloc (buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate space buffer");
+ /* encode space */
+ if(H5Sencode(space_id, value, &buf_size) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode space");
+
+ kv.key = (void *)key;
+ kv.key_len = (iod_size_t)strlen(key);
+ kv.value = value;
+ kv.value_len = (iod_size_t)buf_size;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Dataspace Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+ if(key) {
+ free(key);
+ key = NULL;
+ }
+ if(value) {
+ free(value);
+ value = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_insert_new_link
+ *
+ * Purpose: Function to insert a link to another object in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_insert_new_link(iod_handle_t oh, iod_trans_id_t tid, const char *link_name,
+ H5L_type_t link_type, const void *link_val, uint32_t cs_scope,
+ iod_hint_list_t *hints, iod_event_t *event)
+{
+ iod_kv_t kv;
+ void *value = NULL;
+ uint8_t *val_ptr = NULL;
+ size_t value_len;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch(link_type) {
+ case H5L_TYPE_HARD:
+ {
+ value_len = sizeof(H5L_type_t) + sizeof(iod_obj_id_t);
+ value = malloc(value_len);
+
+ val_ptr = (uint8_t *)value;
+
+ memcpy(val_ptr, &link_type, sizeof(H5L_type_t));
+ memcpy(val_ptr+sizeof(H5L_type_t), link_val, sizeof(iod_obj_id_t));
+
+ break;
+ }
+ case H5L_TYPE_SOFT:
+ {
+ value_len = sizeof(H5L_type_t) + strlen((const char *)link_val) + 1;
+ value = malloc(value_len);
+
+ val_ptr = (uint8_t *)value;
+
+ memcpy(val_ptr, &link_type, sizeof(H5L_type_t));
+ strcpy((char *)(val_ptr+sizeof(H5L_type_t)), (const char *)link_val);
+
+ break;
+ }
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_EXTERNAL:
+ case H5L_TYPE_MAX:
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unsupported link type");
+ }
+
+ kv.key = (void *)link_name;
+ kv.key_len = (iod_size_t)strlen(link_name);
+ kv.value = value;
+ kv.value_len = value_len;
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(kv.key, kv.key_len);
+ cs[1] = H5_checksum_crc64(kv.value, kv.value_len);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Link Type Checksums key = %016lX value = %016lX\n", cs[0], cs[1]);
+#endif
+
+ if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+ else {
+ if (iod_kv_set(oh, tid, hints, &kv, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent");
+ }
+
+done:
+
+ if(value)
+ free(value);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_get_metadata
+ *
+ * Purpose: Function to retrieve a particular metadata value from an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_get_metadata(iod_handle_t oh, iod_trans_id_t tid, H5VL_iod_metadata_t md_type,
+ const char *key, uint32_t cs_scope, iod_event_t *event, void *ret)
+{
+ iod_size_t key_size = strlen(key);
+ iod_size_t val_size = 0;
+ void *value = NULL;
+ iod_checksum_t *iod_cs = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_cs = (iod_checksum_t *)malloc(sizeof(iod_checksum_t) * 2);
+ }
+
+ switch(md_type) {
+ case H5VL_IOD_PLIST:
+ {
+ hid_t plist_id;
+
+ if(iod_kv_get_value(oh, tid, key, key_size, NULL, &val_size, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if((plist_id = H5Pdecode(value)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode cpl");
+
+ *((hid_t *)ret) = plist_id;
+ break;
+ }
+ case H5VL_IOD_LINK_COUNT:
+ val_size = sizeof(uint64_t);
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "link_count lookup failed");
+
+ memcpy(ret, value, val_size);
+ break;
+ case H5VL_IOD_DATATYPE:
+ {
+ hid_t type_id;
+
+ if(iod_kv_get_value(oh, tid, key, key_size, NULL, &val_size, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if((type_id = H5Tdecode(value)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode datatype");
+
+ *((hid_t *)ret) = type_id;
+ break;
+ }
+ case H5VL_IOD_DATASPACE:
+ {
+ hid_t space_id;
+
+ if(iod_kv_get_value(oh, tid, key, key_size, NULL, &val_size, NULL, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ if((space_id = H5Sdecode(value)) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode dataspace");
+
+ *((hid_t *)ret) = space_id;
+ break;
+ }
+ case H5VL_IOD_OBJECT_TYPE:
+ val_size = sizeof(int32_t);
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "link_count lookup failed");
+
+ memcpy(ret, value, val_size);
+ break;
+ case H5VL_IOD_LINK:
+ {
+ H5VL_iod_link_t *iod_link = (H5VL_iod_link_t *)ret;
+ uint8_t *val_ptr;
+ iod_ret_t iod_ret;
+
+ if((iod_ret = iod_kv_get_value(oh, tid, key, key_size, NULL, &val_size, NULL, event)) < 0) {
+ fprintf(stderr, "%d (%s).\n", iod_ret, strerror(-iod_ret));
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+ }
+ if(NULL == (value = malloc((size_t)val_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer");
+
+ if(iod_kv_get_value(oh, tid, key, key_size, value, &val_size, iod_cs, event) < 0)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed");
+
+ val_ptr = (uint8_t *)value;
+
+ iod_link->link_type = *((H5L_type_t *)val_ptr);
+ val_ptr += sizeof(H5L_type_t);
+
+ switch(iod_link->link_type) {
+ case H5L_TYPE_HARD:
+ iod_link->u.iod_id = *((iod_obj_id_t *)val_ptr);
+ break;
+ case H5L_TYPE_SOFT:
+ iod_link->u.symbolic_name = strdup((char *)val_ptr);
+ break;
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_EXTERNAL:
+ case H5L_TYPE_MAX:
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "unsupported link type");
+ }
+ break;
+ }
+ default:
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "invalide metadata type");
+ }
+
+ if(cs_scope & H5_CHECKSUM_IOD) {
+ iod_checksum_t cs[2];
+
+ cs[0] = H5_checksum_crc64(key, key_size);
+ cs[1] = H5_checksum_crc64(value, val_size);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Key CS iod = %016lX computed = %016lX\n", iod_cs[0], cs[0]);
+ fprintf(stderr, "Value CS iod = %016lX computed = %016lX\n", iod_cs[1], cs[1]);
+#endif
+ if(iod_cs[0] != cs[0] && iod_cs[1] != cs[1])
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected when reading metadata from IOD");
+ }
+
+done:
+ if(value) {
+ free(value);
+ value = NULL;
+ }
+
+ if(iod_cs) {
+ free(iod_cs);
+ iod_cs = NULL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_adjust_buffer
+ *
+ * Checks datatypes to see if type conversion is required, if
+ * yes, the buffer is resized accordingly.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL__iod_server_adjust_buffer(hid_t mem_type_id, hid_t dset_type_id, size_t nelmts,
+ hid_t UNUSED dxpl_id, size_t size, void **buf,
+ hbool_t *is_vl_data, size_t *_buf_size)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ switch(H5Tget_class(dset_type_id)) {
+ 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_STRING:
+ if(H5Tis_variable_str(dset_type_id)) {
+ *is_vl_data = TRUE;
+ *_buf_size = size;
+ break;
+ }
+ case H5T_REFERENCE:
+ case H5T_NCLASSES:
+ case H5T_COMPOUND:
+ {
+ hsize_t buf_size = 0;
+ size_t mem_type_size, dset_type_size;
+
+ *is_vl_data = FALSE;
+
+ /* retrieve source and destination datatype sizes for data conversion */
+ mem_type_size = H5Tget_size(mem_type_id);
+ dset_type_size = H5Tget_size(dset_type_id);
+
+ /* adjust buffer size for data conversion */
+ if(mem_type_size < dset_type_size) {
+ buf_size = dset_type_size * nelmts;
+
+ if(NULL == (*buf = realloc(*buf, (size_t)buf_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "Can't adjust buffer for DT conversion");
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Adjusted Buffer size for dt conversion from %zu to %lld\n",
+ size, buf_size);
+#endif
+ }
+ else {
+ buf_size = mem_type_size * nelmts;
+ if(buf_size != size)
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Incoming data size is not equal to expected size");
+ }
+
+ *_buf_size = buf_size;
+
+ break;
+ }
+ case H5T_VLEN:
+ *is_vl_data = TRUE;
+ *_buf_size = size;
+ break;
+ default:
+ HGOTO_ERROR2(H5E_ARGS, H5E_CANTINIT, FAIL, "unsupported datatype");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_server_adjust_buffer */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_verify_scratch_pad
+ *
+ * Purpose: Function to insert the link count in an
+ * IOD KV object.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_iod_verify_scratch_pad(scratch_pad *sp, iod_checksum_t iod_cs)
+{
+ iod_checksum_t computed_cs = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ computed_cs = H5_checksum_crc64(sp, sizeof(scratch_pad));
+
+ if(computed_cs != iod_cs) {
+ fprintf(stderr, "Scratch pad integrity check failed. IOD cs = %"PRIu64", Computed cs = %"PRIu64"\n",
+ iod_cs, computed_cs);
+ ret_value = FAIL;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_iod_verify_scratch_pad() */
+
+herr_t
+H5VL_iod_verify_kv_pair(void *key, iod_size_t key_size, void *value, iod_size_t val_size,
+ iod_checksum_t *iod_cs)
+{
+ iod_checksum_t cs[2];
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ cs[0] = H5_checksum_crc64(key, key_size);
+ cs[1] = H5_checksum_crc64(value, val_size);
+
+#if H5VL_IOD_DEBUG
+ fprintf(stderr, "Key CS iod = %016lX computed = %016lX\n", iod_cs[0], cs[0]);
+ fprintf(stderr, "Value CS iod = %016lX computed = %016lX\n", iod_cs[1], cs[1]);
+#endif
+
+ if(iod_cs[0] != cs[0] && iod_cs[1] != cs[1])
+ HGOTO_ERROR2(H5E_SYM, H5E_CANTINIT, FAIL, "Corruption detected in IOD KV pair");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL_iod_verify_kv_pair */
+
+#if 0
+herr_t
+H5VL_iod_map_type_convert(hid_t src_id, hid_t dst_id, void *buf, size_t buf_size)
+{
+ H5T_class_t class;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ class = H5Tget_class(src_id);
+ if(H5T_VLEN == class || (H5T_STRING == class && H5Tis_variable_str(src_id)))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Can't convert VL or string types");
+
+ class = H5Tget_class(dset_id);
+ if(H5T_VLEN == class || (H5T_STRING == class && H5Tis_variable_str(dst_id)))
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Can't convert VL or string types");
+
+ /* Check (and do) Type conversion on the Key */
+ src_size = H5Tget_size(src_id);
+ dst_size = H5Tget_size(dst_id);
+
+ /* adjust buffer size for datatype conversion */
+ if(src_size < dst_size) {
+ new_size = dst_size;
+ if(NULL == (*buf = realloc(*buf, new_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "Can't adjust buffer for DT conversion");
+ }
+ else {
+ new_size = src_size;
+ }
+
+ if(NULL == (key_buf = malloc((size_t)key_size)))
+ HGOTO_ERROR2(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer");
+ memcpy(key_buf, key.buf, src_size);
+
+ if(H5Tconvert(src_id, dst_id, 1, key_buf, NULL, dxpl_id) < 0)
+ HGOTO_ERROR2(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+#endif
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLiod_view.c b/src/H5VLiod_view.c
new file mode 100644
index 0000000..cf91ee0
--- /dev/null
+++ b/src/H5VLiod_view.c
@@ -0,0 +1,409 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov>
+ * October, 2013
+ *
+ * Purpose: Routines to support Query/View objects.
+ */
+
+
+#include "H5VLiod_server.h"
+
+#ifdef H5_HAVE_EFF
+
+#if 0
+
+static herr_t H5VL__iod_server_construct_view(iod_handle_t coh, iod_obj_id_t loc_id,
+ iod_trans_id_t rtid, hid_t query,
+ size_t *num_tokens, H5VL_token_t *tokens);
+static herr_t H5VL__iod_query_selection(iod_handle_t coh, iod_obj_id_t obj_id,
+ iod_trans_id_t rtid, hid_t query,
+ size_t *num_tokens, H5VL_token_t *tokens);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_get_layout_cb
+ *
+ * Purpose: Retrieves layout of object
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_get_layout_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ get_layout_in_t *input = (get_layout_in_t *)op_data->input;
+ get_layout_out_t output;;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_obj_id_t obj_id = input->obj_id; /* The ID of the object */
+ iod_handle_t obj_oh = input->obj_oh; /* object handle */
+ H5I_type_t loc_type = input->loc_type; /* type of the location where query needs to be applied */
+ iod_trans_id_t rtid = input->rcxt_num;
+ iod_layout_t layout;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(obj_oh.cookie == IOD_OH_UNDEFINED) {
+ if (iod_obj_open_read(coh, obj_id, NULL /*hints*/, &obj_oh, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+ opened_locally = TRUE;
+ }
+
+ if(iod_obj_get_layout(obj_oh, rtid, &layout, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object layout");
+
+ output.ret = ret_value;
+ output.layout = layout
+
+ HG_Handler_start_output(op_data->hg_handle, output);
+
+done:
+
+ if(ret_value < 0)
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (view_create_in_t *)H5MM_xfree(input);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ /* close the dataset if we opened it in this routine */
+ if(opened_locally) {
+ if(iod_obj_close(obj_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+ }
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_get_layout_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_view_create_cb
+ *
+ * Purpose: Creates a view from a provided query.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_view_create_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ view_create_in_t *input = (view_create_in_t *)op_data->input;
+ view_create_out_t *output = NULL;
+ iod_handle_t coh = input->coh; /* the container handle */
+ iod_obj_id_t loc_id = input->loc_id; /* The ID of the object */
+ H5I_type_t loc_type = input->loc_type; /* type of the location where query needs to be applied */
+ hid_t query = input->query; /* query object to apply */
+ iod_trans_id_t rtid = input->rcxt_num;
+ uint32_t cs_scope = input->cs_scope;
+ int token_count;
+ int num_tokens = 0;
+ H5VL_token_t *tokens = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* If the location type is a raw data object, then only 1 token is needed */
+ if(loc_type == H5I_MAP || loc_type == H5I_DATASET || loc_type == H5I_DATATYPE)
+ token_count = 1;
+ /* Otherwise the location type is a group or the root group, so we
+ set the initial number of tokens to the upperbound total number
+ of objects in the container. */
+ else if(loc_type == H5I_GROUP || loc_type == H5I_FILE) {
+ if(iod_container_list_obj(coh, rtid, IOD_OBJ_ANY, 0, &token_count,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve total number of objects in container");
+ }
+
+ if(NULL == (tokens = (H5VL_token_t *)malloc(sizeof(H5VL_token_t) * token_count)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate token structs");
+
+ if(H5VL__iod_server_construct_view(coh, loc_id, rtid, query, &num_tokens, tokens) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to construct view");
+
+ if(NULL == (output = (view_create_out_t *)H5MM_malloc(sizeof(view_create_out_t))))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate output struct for view create");
+
+ output->ret = ret_value;
+ output->num_tokens = num_tokens;
+ output->tokens = tokens;
+ op_data->output = output;
+
+ HG_Handler_start_output(op_data->hg_handle, output);
+
+done:
+
+ if(ret_value < 0)
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (view_create_in_t *)H5MM_xfree(input);
+ output = (view_create_out_t *)H5MM_xfree(output);
+ op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_view_create_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_iod_server_get_view_tokens_cb
+ *
+ * Purpose: Creates a view from a provided query.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * September, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5VL_iod_server_get_view_tokens_cb(AXE_engine_t UNUSED axe_engine,
+ size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[],
+ size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[],
+ void *_op_data)
+{
+ op_data_t *op_data = (op_data_t *)_op_data;
+ view_get_tokens_in_t *input = (view_get_tokens_in_t *)op_data->input;
+ AXE_task_t view_create_id = input->view_create_id;
+ hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */
+ hg_bulk_block_t bulk_block_handle; /* HG block handle */
+ hg_bulk_request_t bulk_request; /* HG request */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+
+ /* Create a new block handle to write the data */
+ HG_Bulk_block_handle_create(buf, size, HG_BULK_READ_ONLY, &bulk_block_handle);
+
+ /* Write bulk data here and wait for the data to be there */
+ if(HG_SUCCESS != HG_Bulk_write_all(dest, bulk_handle, bulk_block_handle, &bulk_request))
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+ /* wait for it to complete */
+ if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE))
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object");
+
+ /* free block handle */
+ if(HG_SUCCESS != HG_Bulk_block_handle_free(bulk_block_handle))
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't free bds block handle");
+
+ HG_Handler_start_output(op_data->hg_handle, output);
+
+done:
+
+ if(ret_value < 0)
+ HG_Handler_start_output(op_data->hg_handle, &ret_value);
+
+ input = (object_op_in_t *)H5MM_xfree(input);
+ //op_data = (op_data_t *)H5MM_xfree(op_data);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5VL_iod_server_get_view_tokens_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_server_construct_view
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_server_construct_view(iod_handle_t coh, iod_obj_id_t loc_id, iod_trans_id_t rtid,
+ hid_t query, int *num_tokens, H5VL_token_t *tokens)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get tokens for attributes that satisfy the query on the current
+ location object */
+ if(query_type & H5Q_TYPE_ATTR_NAME) {
+ if(H5VL_iod_query_attribute(coh, rtid, loc_id, query, num_tokens, tokens) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to query dataset for selection");
+ }
+
+ if(loc_id & IOD_OBJ_TYPE_ARRAY) {
+ /* get token for dataset and space selection for data
+ elements that satisfy the query */
+ if(H5VL_iod_query_selection(coh, rtid, loc_id, query, num_tokens, tokens) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to query dataset for selection");
+ }
+
+ else if(loc_id & IOD_OBJ_TYPE_KV) {
+ /* get tokens for links that satisfy the query on the current
+ location object. This will recursively call
+ H5VL_iod_server_construct_view() on every object ID that
+ has a link from the current location object. */
+ if(query_type & H5Q_TYPE_LINK_NAME) {
+ if(H5VL_iod_query_link(coh, rtid, loc_id, query, num_tokens, tokens) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to query dataset for selection");
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_server_construct_view() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__iod_query_selection
+ *
+ * Purpose:
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__iod_query_selection(iod_handle_t coh, iod_obj_id_t obj_id,
+ iod_trans_id_t rtid, hid_t query,
+ int *num_tokens, H5VL_token_t *tokens)
+{
+ iod_handle_t obj_oh = IOD_OH_UNDEFINED;
+ hid_t layout_space = -1, queried_space = -1;
+ size_t nelmts;
+ size_t elmt_size;
+ size_t buf_size=0, ds_size=0, dt_size=0;
+ void *buf = NULL;
+ scratch_pad sp;
+ H5O_type_t otype;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* open the array object */
+ if (iod_obj_open_read(coh, obj_id, NULL /*hints*/, &obj_oh, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group");
+
+ /* get scratch pad of the dataset */
+ if(iod_obj_get_scratch(obj_oh, rtid, &sp, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't get scratch pad for object");
+
+ /* open the metadata scratch pad */
+ if (iod_obj_open_write(coh, sp[0], NULL /*hints*/, &mdkv_oh, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad");
+
+ /* retrieve the datatype of array object */
+ if(H5VL_iod_get_metadata(mdkv_oh, rtid, H5VL_IOD_DATATYPE, H5VL_IOD_KEY_OBJ_DATATYPE,
+ NULL, NULL, type_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype");
+
+ /* close the metadata scratch pad */
+ if(iod_obj_close(mdkv_oh, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object");
+
+ /* get layout dataspace from the query to read from */
+ layout_space = H5Qget_space(query);
+
+ nelmts = (size_t)H5Sget_select_npoints(layout_space);
+ elmt_size = H5Tget_size(type_id);
+ buf_size = nelmts * elmt_size;
+
+ /* allocate buffer to hold data */
+ if(NULL == (buf = malloc(buf_size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* read the data selection from IOD. */
+ /* MSC - will need to do it in pieces, not it one shot. */
+ if(H5VL__iod_server_final_io(coh, obj_oh, layout_space, type_id,
+ FALSE, buf, buf_size, 0, 0, rtid) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREAD, FAIL, "can't read from array object");
+
+ if(H5Qapply(query, buf, type_id, layout_space, H5P_DEFAULT, &queried_space) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't apply query on dataspace");
+
+ if(H5Sencode(queried_space, NULL, &ds_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace");
+ if(H5Tencode(type_id, NULL, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype");
+
+ token_size += sizeof(iod_obj_id_t)*3 + sizeof(H5O_type_t) +
+ dt_size + ds_size + sizeof(size_t)*2;
+
+ u = *num_tokens;
+ tokens[u].token_size = token_size;
+
+ if(NULL == (tokens[u].token = malloc(token_size)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate token buffer");
+
+ buf_ptr = (uint8_t *)tokens[u].token;
+
+ HDmemcpy(buf_ptr, &obj_id, sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(buf_ptr, &sp[0], sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ HDmemcpy(buf_ptr, &sp[1], sizeof(iod_obj_id_t));
+ buf_ptr += sizeof(iod_obj_id_t);
+ otype = H5O_TYPE_DATASET;
+ HDmemcpy(buf_ptr, &otype, sizeof(H5O_type_t));
+ buf_ptr += sizeof(H5O_type_t);
+
+ HDmemcpy(buf_ptr, &dt_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5Tencode(type_id, buf_ptr, &dt_size) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype");
+ buf_ptr += dt_size;
+
+ HDmemcpy(buf_ptr, &ds_size, sizeof(size_t));
+ buf_ptr += sizeof(size_t);
+ if(H5Sencode(queried_space, buf_ptr, &ds_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace");
+ buf_ptr += space_size;
+
+ *num_tokens ++;
+
+done:
+
+ if(layout_space)
+ H5Sclose(layout_space);
+ if(queried_space)
+ H5Sclose(queried_space);
+
+ if(buf)
+ free(buf);
+
+ if(obj_oh != IOD_OH_UNDEFINED && iod_obj_close(obj_oh, NULL, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object");
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__iod_query_selection() */
+#endif
+
+#endif /* H5_HAVE_EFF */
diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h
index 33f3f5a..143cbf9 100644
--- a/src/H5VLprivate.h
+++ b/src/H5VLprivate.h
@@ -29,8 +29,6 @@
/****************************/
/* Library Private Typedefs */
/****************************/
-#define H5_REQUEST_NULL NULL
-#define H5_EVENT_STACK_NULL -1
/*****************************/
/* Library Private Variables */
diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h
index 1171811..8a2ee06 100644
--- a/src/H5VLpublic.h
+++ b/src/H5VLpublic.h
@@ -23,20 +23,13 @@
#include "stdarg.h"
#include "H5public.h"
+#include "H5ESpublic.h"
#include "H5Apublic.h" /* Attributes */
#include "H5Fpublic.h"
#include "H5Lpublic.h"
#include "H5Opublic.h"
#include "H5Rpublic.h"
-/* Asynchronous operation status */
-typedef enum H5ES_status_t {
- H5ES_STATUS_IN_PROGRESS, /* Operation has not yet completed */
- H5ES_STATUS_SUCCEED, /* Operation has completed, successfully */
- H5ES_STATUS_FAIL, /* Operation has completed, but failed */
- H5ES_STATUS_CANCEL /* Operation has not completed and has been cancelled */
-} H5ES_status_t;
-
/* Dataset creation property names */
#define H5VL_DSET_TYPE_ID "dataset_type_id"
#define H5VL_DSET_SPACE_ID "dataset_space_id"
@@ -188,6 +181,7 @@ struct H5VL_loc_by_idx {
struct H5VL_loc_by_addr {
haddr_t addr;
+ H5O_type_t obj_type;
};
struct H5VL_loc_by_ref {
@@ -301,7 +295,7 @@ typedef struct H5VL_object_class_t {
herr_t (*close) (void *obj, H5VL_loc_params_t loc_params, hid_t dxpl_id, void **req);
} H5VL_object_class_t;
-/* H5AO routines */
+/* async routines */
typedef struct H5VL_async_class_t {
herr_t (*cancel)(void **, H5ES_status_t *);
herr_t (*test) (void **, H5ES_status_t *);
@@ -311,6 +305,7 @@ typedef struct H5VL_async_class_t {
/* enum value to identify the class of a VOL plugin (mostly for comparison purposes) */
typedef enum H5VL_class_value_t {
NATIVE = 0, /* This should be first */
+ IOD = 1,
MAX_VOL_LIB_VALUE = 128 /* This should be last */
} H5VL_class_value_t;
@@ -343,6 +338,8 @@ struct H5VL_t {
const char *container_name; /* name of the underlying storage container */
unsigned long feature_flags; /* VOL Driver feature Flags */
int nrefs; /* number of references by objects using this struct */
+ hid_t close_estack_id;
+ hid_t close_dxpl_id;
};
#ifdef __cplusplus
diff --git a/src/H5checksum.c b/src/H5checksum.c
index 48e4ce5..727bdf7 100644
--- a/src/H5checksum.c
+++ b/src/H5checksum.c
@@ -34,7 +34,6 @@
/***********/
#include "H5private.h" /* Generic Functions */
-
/****************/
/* Local Macros */
/****************/
@@ -79,7 +78,6 @@ static uint32_t H5_crc_table[256];
/* Flag: has the table been computed? */
static hbool_t H5_crc_table_computed = FALSE;
-
/*-------------------------------------------------------------------------
* Function: H5_checksum_fletcher32
@@ -432,6 +430,177 @@ done:
FUNC_LEAVE_NOAPI(c)
} /* end H5_checksum_lookup3() */
+uint32_t
+H5_checksum_lookup4(const void *key, size_t length, H5_checksum_seed_t *cs)
+{
+ const uint8_t *k = (const uint8_t *)key;
+ uint32_t position = 0;
+ uint32_t a, b, c; /* internal state */
+ int pos = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Sanity check */
+ HDassert(key);
+ HDassert(length > 0);
+
+ /* Set up the internal state */
+ if(cs) {
+ if(!cs->a && !cs->b && !cs->c) {
+ a = b = c = 0xdeadbeef;// + ((uint32_t)cs->total_length);
+ /* Compute new State */
+ cs->state = 12 - (length % 12);
+ }
+ else {
+ a = cs->a;
+ b = cs->b;
+ c = cs->c;
+
+ /* determine position to start up on */
+ if(cs->state) {
+ position = 12 - cs->state + 1;
+ }
+
+ /* Compute new State */
+ cs->state = cs->state - (length % 12);
+ if(cs->state < 0) {
+ H5_lookup3_mix(a, b, c);
+ cs->state = 12 + cs->state;
+ }
+
+ /* Move towards mod 12 */
+ switch(position)
+ {
+ case 0 :
+ break;
+ case 1 :
+ a+=k[pos++];
+ length --;
+ if(0 == length)
+ break;
+ case 2 :
+ a+=((uint32_t)k[pos++])<<8;
+ length --;
+ if(0 == length)
+ break;
+ case 3 :
+ a+=((uint32_t)k[pos++])<<16;
+ length --;
+ if(0 == length)
+ break;
+ case 4 :
+ a+=((uint32_t)k[pos++])<<24;
+ length --;
+ if(0 == length)
+ break;
+ case 5 :
+ b+=k[pos++];
+ length --;
+ if(0 == length)
+ break;
+ case 6 :
+ b+=((uint32_t)k[pos++])<<8;
+ length --;
+ if(0 == length)
+ break;
+ case 7 :
+ b+=((uint32_t)k[pos++])<<16;
+ length --;
+ if(0 == length)
+ break;
+ case 8 :
+ b+=((uint32_t)k[pos++])<<24;
+ length --;
+ if(0 == length)
+ break;
+ case 9 :
+ c+=k[pos++];
+ length --;
+ if(0 == length)
+ break;
+ case 10:
+ c+=((uint32_t)k[pos++])<<8;
+ length --;
+ if(0 == length)
+ break;
+ case 11:
+ c+=((uint32_t)k[pos++])<<16;
+ length --;
+ if(0 == length)
+ break;
+ case 12:
+ c+=((uint32_t)k[pos++])<<24;
+ length --;
+ if(0 == length)
+ break;
+ H5_lookup3_mix(a, b, c);
+ break;
+ }
+ }
+ /* capture internal state if we are done at this stage */
+ if(0 == length) {
+ cs->a = a;
+ cs->b = b;
+ cs->c = c;
+ H5_lookup3_final(a, b, c);
+ goto done;
+ }
+ }
+ else
+ a = b = c = 0xdeadbeef; //+ ((uint32_t)length);
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0+pos];
+ a += ((uint32_t)k[1+pos])<<8;
+ a += ((uint32_t)k[2+pos])<<16;
+ a += ((uint32_t)k[3+pos])<<24;
+ b += k[4+pos];
+ b += ((uint32_t)k[5+pos])<<8;
+ b += ((uint32_t)k[6+pos])<<16;
+ b += ((uint32_t)k[7+pos])<<24;
+ c += k[8+pos];
+ c += ((uint32_t)k[9+pos])<<8;
+ c += ((uint32_t)k[10+pos])<<16;
+ c += ((uint32_t)k[11+pos])<<24;
+ H5_lookup3_mix(a, b, c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32_t)k[11+pos])<<24;
+ case 11: c+=((uint32_t)k[10+pos])<<16;
+ case 10: c+=((uint32_t)k[9+pos])<<8;
+ case 9 : c+=k[8+pos];
+ case 8 : b+=((uint32_t)k[7+pos])<<24;
+ case 7 : b+=((uint32_t)k[6+pos])<<16;
+ case 6 : b+=((uint32_t)k[5+pos])<<8;
+ case 5 : b+=k[4+pos];
+ case 4 : a+=((uint32_t)k[3+pos])<<24;
+ case 3 : a+=((uint32_t)k[2+pos])<<16;
+ case 2 : a+=((uint32_t)k[1+pos])<<8;
+ case 1 : a+=k[pos];
+ break;
+ case 0 : goto done;
+ }
+
+ /* capture internal state */
+ if(cs) {
+ cs->a = a;
+ cs->b = b;
+ cs->c = c;
+ }
+
+ H5_lookup3_final(a, b, c);
+
+done:
+ FUNC_LEAVE_NOAPI(c)
+} /* end H5_checksum_lookup3() */
+
/*-------------------------------------------------------------------------
* Function: H5_checksum_metadata
@@ -493,4 +662,3 @@ H5_hash_string(const char *str)
FUNC_LEAVE_NOAPI(hash)
} /* end H5_hash_string() */
-
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 02bafd8..d99c709 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -61,6 +61,9 @@
/* Define if the __attribute__(()) extension is present */
#undef HAVE_ATTRIBUTE
+/* Define to 1 if you have the <axe.h> header file. */
+#undef HAVE_AXE_H
+
/* Define to 1 if you have the `BSDgettimeofday' function. */
#undef HAVE_BSDGETTIMEOFDAY
@@ -77,6 +80,12 @@
/* Define if the function stack tracing code is to be compiled in */
#undef HAVE_CODESTACK
+/* Define to 1 if you have the <daos_api.h> header file. */
+#undef HAVE_DAOS_API_H
+
+/* Define to 1 if you have the <daos_types.h> header file. */
+#undef HAVE_DAOS_TYPES_H
+
/* Define if Darwin or Mac OS X */
#undef HAVE_DARWIN
@@ -99,6 +108,9 @@
/* Define to 1 if you have the <dmalloc.h> header file. */
#undef HAVE_DMALLOC_H
+/* Define if we have EFF VOL plugins support */
+#undef HAVE_EFF
+
/* Define if library information should be embedded in the executables */
#undef HAVE_EMBEDDED_LIBINFO
@@ -190,21 +202,39 @@
/* Define to 1 if you have the `ioctl' function. */
#undef HAVE_IOCTL
+/* Define to 1 if you have the <iod_api.h> header file. */
+#undef HAVE_IOD_API_H
+
+/* Define to 1 if you have the <iod_types.h> header file. */
+#undef HAVE_IOD_TYPES_H
+
/* Define to 1 if you have the <io.h> header file. */
#undef HAVE_IO_H
+/* Define to 1 if you have the `axe' library (-laxe). */
+#undef HAVE_LIBAXE
+
+/* Define to 1 if you have the `daos_posix' library (-ldaos_posix). */
+#undef HAVE_LIBDAOS_POSIX
+
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
/* Define to 1 if you have the `dmalloc' library (-ldmalloc). */
#undef HAVE_LIBDMALLOC
+/* Define to 1 if you have the `iod' library (-liod). */
+#undef HAVE_LIBIOD
+
/* Define to 1 if you have the `lmpe' library (-llmpe). */
#undef HAVE_LIBLMPE
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
+/* Define to 1 if you have the `mdhim' library (-lmdhim). */
+#undef HAVE_LIBMDHIM
+
/* Define to 1 if you have the `mpe' library (-lmpe). */
#undef HAVE_LIBMPE
@@ -220,6 +250,12 @@
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
+/* Define to 1 if you have the `pbl' library (-lpbl). */
+#undef HAVE_LIBPBL
+
+/* Define to 1 if you have the `plfs' library (-lplfs). */
+#undef HAVE_LIBPLFS
+
/* Define to 1 if you have the `pthread' library (-lpthread). */
#undef HAVE_LIBPTHREAD
@@ -265,12 +301,27 @@
/* Define if `MPI_Info_c2f' and `MPI_Info_f2c' exists */
#undef HAVE_MPI_MULTI_LANG_Info
+/* Define to 1 if you have the <numpy/ndarrayobject.h> header file. */
+#undef HAVE_NUMPY_NDARRAYOBJECT_H
+
/* Define if we have parallel support */
#undef HAVE_PARALLEL
+/* Define to 1 if you have the <plfs.h> header file. */
+#undef HAVE_PLFS_H
+
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
+/* Define if we have Python support */
+#undef HAVE_PYTHON
+
+/* Define to 1 if you have the <Python.h> header file. */
+#undef HAVE_PYTHON_H
+
+/* Define if we have Python NumPy support */
+#undef HAVE_PYTHON_NUMPY
+
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
diff --git a/src/H5err.txt b/src/H5err.txt
index c3908e4..f126066 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -69,6 +69,7 @@ MAJOR, H5E_EFL, External file list
MAJOR, H5E_REFERENCE, References
MAJOR, H5E_VFL, Virtual File Layer
MAJOR, H5E_VOL, Virtual Object Layer
+MAJOR, H5E_QUERY, Query
MAJOR, H5E_TST, Ternary Search Trees
MAJOR, H5E_RS, Reference Counted Strings
MAJOR, H5E_ERROR, Error API
diff --git a/src/H5private.h b/src/H5private.h
index 859f518..0e3df0d 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2391,13 +2391,18 @@ H5_DLL int H5A_term_interface(void);
H5_DLL int H5AC_term_interface(void);
H5_DLL int H5D_term_interface(void);
H5_DLL int H5E_term_interface(void);
+H5_DLL int H5ES_term_interface(void);
+H5_DLL int H5RC_term_interface(void);
+H5_DLL int H5TR_term_interface(void);
H5_DLL int H5F_term_interface(void);
H5_DLL int H5FS_term_interface(void);
H5_DLL int H5G_term_interface(void);
H5_DLL int H5I_term_interface(void);
H5_DLL int H5L_term_interface(void);
+H5_DLL int H5M_term_interface(void);
H5_DLL int H5P_term_interface(void);
H5_DLL int H5PL_term_interface(void);
+H5_DLL int H5Q_term_interface(void);
H5_DLL int H5R_term_interface(void);
H5_DLL int H5S_term_interface(void);
H5_DLL int H5T_term_interface(void);
@@ -2407,6 +2412,7 @@ H5_DLL int H5Z_term_interface(void);
H5_DLL uint32_t H5_checksum_fletcher32(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_crc(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initval);
+H5_DLL uint32_t H5_checksum_lookup4(const void *data, size_t len, H5_checksum_seed_t *cs);
H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval);
H5_DLL uint32_t H5_hash_string(const char *str);
diff --git a/src/H5public.h b/src/H5public.h
index 5bfc909..9874fb1 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -94,6 +94,10 @@ extern "C" {
((H5_VERS_MAJOR==Maj) && (H5_VERS_MINOR<Min)) || \
(H5_VERS_MAJOR<Maj))
+#ifdef H5_HAVE_EFF
+typedef uint64_t hrpl_t;
+#endif /* H5_HAVE_EFF */
+
/*
* Status return values. Failed integer functions in HDF5 result almost
* always in a negative value (unsigned failing functions sometimes return
@@ -106,7 +110,6 @@ extern "C" {
*/
typedef int herr_t;
-
/*
* Boolean type. Successful return values are zero (false) or positive
* (true). The typical true value is 1 but don't bet on it. Boolean
@@ -301,6 +304,15 @@ typedef struct H5_ih_info_t {
hsize_t heap_size;
} H5_ih_info_t;
+/* Internal Checksum state */
+typedef struct H5_checksum_seed_t {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ int32_t state;
+ size_t total_length;
+} H5_checksum_seed_t;
+
/* Functions in H5.c */
H5_DLL herr_t H5open(void);
H5_DLL herr_t H5close(void);
@@ -313,6 +325,7 @@ H5_DLL herr_t H5get_libversion(unsigned *majnum, unsigned *minnum,
unsigned *relnum);
H5_DLL herr_t H5check_version(unsigned majnum, unsigned minnum,
unsigned relnum);
+H5_DLL uint32_t H5checksum(const void *key, size_t length, H5_checksum_seed_t *cs);
#ifdef __cplusplus
}
diff --git a/src/H5trace.c b/src/H5trace.c
index 6dcabd0..5f18869 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -40,6 +40,9 @@
#include "H5Ipkg.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Qpublic.h" /* Queries */
+#include "H5RCpublic.h" /* Read Contexts */
+
#ifdef H5_HAVE_PARALLEL
/* datatypes of predefined drivers needed by H5_trace() */
#include "H5FDmpio.h"
@@ -1159,6 +1162,26 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
fprintf(out, "%ld (group)", (long)obj);
break;
+ case H5I_MAP:
+ fprintf(out, "%ld (map)", (long)obj);
+ break;
+
+ case H5I_RC:
+ fprintf(out, "%ld (read context)", (long)obj);
+ break;
+
+ case H5I_TR:
+ fprintf(out, "%ld (transaction)", (long)obj);
+ break;
+
+ case H5I_QUERY:
+ fprintf(out, "%ld (query)", (long)obj);
+ break;
+
+ case H5I_VIEW:
+ fprintf(out, "%ld (view)", (long)obj);
+ break;
+
case H5I_DATATYPE:
if(obj == H5T_NATIVE_SCHAR_g)
fprintf(out, "H5T_NATIVE_SCHAR");
@@ -1285,6 +1308,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
fprintf(out, "%ld (object driver)", (long)obj);
break;
+ case H5I_ES:
+ fprintf(out, "%ld (event queue)", (long)obj);
+ break;
+
case H5I_GENPROP_CLS:
fprintf(out, "%ld (genprop class)", (long)obj);
break;
@@ -1415,6 +1442,30 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end else */
break;
+ case 'l':
+ if(ptr) {
+ if(vp) {
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ if(asize_idx >= 0 && asize[asize_idx] >= 0) {
+ int *p = (int*)vp;
+
+ fprintf(out, " {");
+ for(i = 0; i < asize[asize_idx]; i++)
+ fprintf(out, "%s%d", (i ? ", " : ""), p[i]);
+ fprintf(out, "}");
+ } /* end if */
+ } /* end if */
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ uint64_t is = va_arg(ap, uint64_t);
+
+ fprintf (out, "%llu", is);
+ asize[argno] = is;
+ } /* end else */
+ break;
+
case 't':
if(ptr) {
if(vp)
@@ -1442,6 +1493,26 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
fprintf(out, "H5I_GROUP");
break;
+ case H5I_MAP:
+ fprintf(out, "H5I_MAP");
+ break;
+
+ case H5I_RC:
+ fprintf(out, "H5I_RC");
+ break;
+
+ case H5I_TR:
+ fprintf(out, "H5I_TR");
+ break;
+
+ case H5I_QUERY:
+ fprintf(out, "H5I_QUERY");
+ break;
+
+ case H5I_VIEW:
+ fprintf(out, "H5I_VIEW");
+ break;
+
case H5I_DATATYPE:
fprintf(out, "H5I_DATATYPE");
break;
@@ -1470,6 +1541,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
fprintf(out, "H5I_VOL");
break;
+ case H5I_ES:
+ fprintf(out, "H5I_ES");
+ break;
+
case H5I_GENPROP_CLS:
fprintf(out, "H5I_GENPROP_CLS");
break;
@@ -1705,6 +1780,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
fprintf(out, "H5O_TYPE_GROUP");
break;
+ case H5O_TYPE_MAP:
+ fprintf(out, "H5O_TYPE_MAP");
+ break;
+
case H5O_TYPE_DATASET:
fprintf(out, "H5O_TYPE_DATASET");
break;
@@ -1768,6 +1847,92 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end else */
break;
+ case 'Q':
+ switch(type[1]) {
+ case 't':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5Q_type_t qtype = (H5Q_type_t)va_arg(ap, int);
+
+ switch(qtype) {
+ case H5Q_TYPE_DATA_ELEM:
+ fprintf(out, "H5Q_TYPE_DATA_ELEM");
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ fprintf(out, "H5Q_TYPE_ATTR_NAME");
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ fprintf(out, "H5Q_TYPE_LINK_NAME");
+ break;
+ default:
+ fprintf(out, "BADTYPE(%d)", qtype);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+ case 'm':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5Q_match_op_t qmatch = (H5Q_match_op_t)va_arg(ap, int);
+
+ switch(qmatch) {
+ case H5Q_MATCH_EQUAL:
+ fprintf(out, "H5Q_MATCH_EQUAL");
+ break;
+ case H5Q_MATCH_NOT_EQUAL:
+ fprintf(out, "H5Q_MATCH_NOT_EQUAL");
+ break;
+ case H5Q_MATCH_LESS_THAN:
+ fprintf(out, "H5Q_MATCH_LESS_THAN");
+ break;
+ case H5Q_MATCH_GREATER_THAN:
+ fprintf(out, "H5Q_MATCH_GREATER_THAN");
+ break;
+ default:
+ fprintf(out, "BADTYPE(%d)", qmatch);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+ case 'c':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5Q_combine_op_t qcomb = (H5Q_combine_op_t)va_arg(ap, int);
+
+ switch(qcomb) {
+ case H5Q_COMBINE_AND:
+ fprintf(out, "H5Q_COMBINE_AND");
+ break;
+ case H5Q_COMBINE_OR:
+ fprintf(out, "H5Q_COMBINE_OR");
+ break;
+ default:
+ fprintf(out, "BADTYPE(%d)", qcomb);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+ default:
+ fprintf(out, "BADTYPE(S%c)", type[1]);
+ goto error;
+ } /* end switch */
+ break;
+
case 'R':
switch(type[1]) {
case 't':
@@ -1803,7 +1968,61 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end switch */
} /* end else */
break;
+#ifdef H5_HAVE_EFF
+ case 'c':
+ if(ptr) {
+ if(vp)
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5RC_request_t request = (H5RC_request_t)va_arg(ap, int);
+
+ switch(request) {
+ case H5RC_EXACT:
+ fprintf(out, "H5RC_EXACT");
+ break;
+ case H5RC_PREV:
+ fprintf(out, "H5RC_PREV");
+ break;
+ case H5RC_NEXT:
+ fprintf(out, "H5RC_NEXT");
+ break;
+ case H5RC_LAST:
+ fprintf(out, "H5RC_LAST");
+ break;
+ default:
+ fprintf(out, "BADTYPE(%ld)", (long)request);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
+
+ case 'p':
+ if(ptr) {
+ if(vp) {
+ fprintf(out, "0x%lx", (unsigned long)vp);
+ if(asize_idx >= 0 && asize[asize_idx] >= 0) {
+ int *p = (int*)vp;
+
+ fprintf(out, " {");
+ for(i = 0; i < asize[asize_idx]; i++)
+ fprintf(out, "%s%d", (i ? ", " : ""), p[i]);
+ fprintf(out, "}");
+ } /* end if */
+ } /* end if */
+ else
+ fprintf(out, "NULL");
+ } /* end if */
+ else {
+ hrpl_t replica_id = va_arg(ap, hrpl_t);
+ fprintf (out, "%"PRIx64"", replica_id);
+ asize[argno] = replica_id;
+ } /* end else */
+ break;
+#endif
default:
fprintf(out, "BADTYPE(S%c)", type[1]);
goto error;
diff --git a/src/Makefile.am b/src/Makefile.am
index 7e843a0..8511b96 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,9 +59,13 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \
H5FAstat.c H5FAtest.c \
H5VL.c H5VLint.c H5VLnative.c \
+ H5VLiod.c H5VLiod_common.c H5VLiod_client.c H5VLiod_server.c H5VLiod_encdec.c H5VLiod_util.c \
+ H5VLiod_file.c H5VLiod_group.c H5VLiod_map.c H5VLiod_dset.c H5VLiod_dtype.c \
+ H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c H5VLiod_trans.c H5VLiod_analysis.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
+ H5FF.c H5ES.c H5RC.c H5TR.c H5M.c H5AS.c\
H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \
H5G.c H5Gbtree2.c H5Gcache.c \
H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
@@ -88,9 +92,10 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \
H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
- H5Pgcpl.c H5Pint.c \
+ H5Pgcpl.c H5Pmcpl.c H5Pmapl.c H5Pint.c H5Prcapl.c H5Ptrspl.c H5Ptrfpl.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5PL.c \
+ H5Q.c \
H5R.c H5Rdeprec.c \
H5UC.c \
H5RS.c \
@@ -117,10 +122,12 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \
H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \
H5FDmulti.h H5FDsec2.h H5FDstdio.h \
- H5VLpublic.h H5VLnative.h \
+ H5VLpublic.h H5VLnative.h H5VLiod.h \
+ H5FFpublic.h H5ESpublic.h H5RCpublic.h H5TRpublic.h H5Mpublic.h H5ASpublic.h\
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
H5MMpublic.h H5Opublic.h H5Ppublic.h \
H5PLextern.h \
+ H5Qpublic.h \
H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5Zpublic.h
diff --git a/src/Makefile.in b/src/Makefile.in
index 8408524..595b0dd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -81,7 +81,9 @@ noinst_PROGRAMS = H5detect$(EXEEXT) H5make_libsettings$(EXEEXT)
TESTS =
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/m4/ax_python.m4 \
+ $(top_srcdir)/m4/ax_python_devel.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/bin/mkinstalldirs
@@ -135,10 +137,16 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \
H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \
H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5VL.lo \
- H5VLint.lo H5VLnative.lo H5FD.lo H5FDcore.lo H5FDdirect.lo \
- H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
- H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \
- H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
+ H5VLint.lo H5VLnative.lo H5VLiod.lo H5VLiod_common.lo \
+ H5VLiod_client.lo H5VLiod_server.lo H5VLiod_encdec.lo \
+ H5VLiod_util.lo H5VLiod_file.lo H5VLiod_group.lo \
+ H5VLiod_map.lo H5VLiod_dset.lo H5VLiod_dtype.lo \
+ H5VLiod_attr.lo H5VLiod_link.lo H5VLiod_obj.lo \
+ H5VLiod_trans.lo H5VLiod_analysis.lo H5FD.lo H5FDcore.lo \
+ H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo \
+ H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo \
+ H5FDspace.lo H5FDstdio.lo H5FF.lo H5ES.lo H5RC.lo H5TR.lo \
+ H5M.lo H5AS.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \
H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \
H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \
@@ -159,8 +167,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \
H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \
H5Pdxpl.lo H5Pencdec.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \
- H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \
- H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5PL.lo H5R.lo \
+ H5Pgcpl.lo H5Pmcpl.lo H5Pmapl.lo H5Pint.lo H5Prcapl.lo \
+ H5Ptrspl.lo H5Ptrfpl.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \
+ H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5PL.lo H5Q.lo H5R.lo \
H5Rdeprec.lo H5UC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \
H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \
H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \
@@ -290,6 +299,7 @@ DYNAMIC_DIRS = @DYNAMIC_DIRS@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
+EFF = @EFF@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
EXTERNAL_FILTERS = @EXTERNAL_FILTERS@
@@ -354,9 +364,17 @@ LT_STATIC_EXEC = @LT_STATIC_EXEC@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
+MCHECKSUM_CFLAGS = @MCHECKSUM_CFLAGS@
+MCHECKSUM_LIBS = @MCHECKSUM_LIBS@
+MERCURY_CFLAGS = @MERCURY_CFLAGS@
+MERCURY_LIBS = @MERCURY_LIBS@
MKDIR_P = @MKDIR_P@
MPE = @MPE@
MPI_GET_SIZE = @MPI_GET_SIZE@
+MYAXE_LIBS = @MYAXE_LIBS@
+MYDAOS_POSIX_LIBS = @MYDAOS_POSIX_LIBS@
+MYIOD_LIBS = @MYIOD_LIBS@
+MYPLFS_LIBS = @MYPLFS_LIBS@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
@@ -374,6 +392,19 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PARALLEL = @PARALLEL@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PYTHON = @PYTHON@
+PYTHON_BIN = @PYTHON_BIN@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_INCLUDE_DIR = @PYTHON_INCLUDE_DIR@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_LIB = @PYTHON_LIB@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
ROOT = @ROOT@
RUNPARALLEL = @RUNPARALLEL@
@@ -554,9 +585,13 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \
H5FAstat.c H5FAtest.c \
H5VL.c H5VLint.c H5VLnative.c \
+ H5VLiod.c H5VLiod_common.c H5VLiod_client.c H5VLiod_server.c H5VLiod_encdec.c H5VLiod_util.c \
+ H5VLiod_file.c H5VLiod_group.c H5VLiod_map.c H5VLiod_dset.c H5VLiod_dtype.c \
+ H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c H5VLiod_trans.c H5VLiod_analysis.c \
H5FD.c H5FDcore.c \
H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \
+ H5FF.c H5ES.c H5RC.c H5TR.c H5M.c H5AS.c\
H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \
H5G.c H5Gbtree2.c H5Gcache.c \
H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
@@ -583,9 +618,10 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \
H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
- H5Pgcpl.c H5Pint.c \
+ H5Pgcpl.c H5Pmcpl.c H5Pmapl.c H5Pint.c H5Prcapl.c H5Ptrspl.c H5Ptrfpl.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5PL.c \
+ H5Q.c \
H5R.c H5Rdeprec.c \
H5UC.c \
H5RS.c \
@@ -612,10 +648,12 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \
H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \
H5FDmulti.h H5FDsec2.h H5FDstdio.h \
- H5VLpublic.h H5VLnative.h \
+ H5VLpublic.h H5VLnative.h H5VLiod.h \
+ H5FFpublic.h H5ESpublic.h H5RCpublic.h H5TRpublic.h H5Mpublic.h H5ASpublic.h\
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
H5MMpublic.h H5Opublic.h H5Ppublic.h \
H5PLextern.h \
+ H5Qpublic.h \
H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5Zpublic.h
@@ -757,6 +795,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5A.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5AC.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5AS.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Abtree2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Adense.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Adeprec.Plo@am__quote@
@@ -803,6 +842,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAsblock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAstat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5EAtest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5ES.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Edeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Eint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5F.Plo@am__quote@
@@ -827,6 +867,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDsec2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDspace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDstdio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FL.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FO.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FS.Plo@am__quote@
@@ -897,6 +938,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Itest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5M.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MFaggr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MFdbg.Plo@am__quote@
@@ -952,11 +994,18 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plcpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pmapl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pmcpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpypl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Prcapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pstrcpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ptest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ptrfpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ptrspl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Q.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5R.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5RC.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5RS.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Rdeprec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5S.Plo@am__quote@
@@ -976,6 +1025,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Sselect.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Stest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5T.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5TR.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5TS.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tarray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tbit.Plo@am__quote@
@@ -1003,6 +1053,22 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5UC.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VL.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_analysis.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_attr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_client.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_dset.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_dtype.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_encdec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_group.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_link.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_obj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_server.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_trans.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLiod_util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLnative.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VM.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5WB.Plo@am__quote@
diff --git a/src/hdf5.h b/src/hdf5.h
index 4a6631e..c46c694 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -26,22 +26,28 @@
#include "H5ACpublic.h" /* Metadata cache */
#include "H5Dpublic.h" /* Datasets */
#include "H5Epublic.h" /* Errors */
+#include "H5ESpublic.h" /* Event Stacks */
#include "H5Fpublic.h" /* Files */
#include "H5FDpublic.h" /* File drivers */
+#include "H5FFpublic.h" /* FastForward wrappers */
#include "H5Gpublic.h" /* Groups */
#include "H5Ipublic.h" /* ID management */
#include "H5Lpublic.h" /* Links */
#include "H5MMpublic.h" /* Memory management */
#include "H5Opublic.h" /* Object headers */
#include "H5Ppublic.h" /* Property lists */
+#include "H5Qpublic.h" /* Queries */
#include "H5Rpublic.h" /* References */
+#include "H5RCpublic.h" /* Read Contexts */
#include "H5Spublic.h" /* Dataspaces */
#include "H5Tpublic.h" /* Datatypes */
+#include "H5TRpublic.h" /* Transcations */
#include "H5Zpublic.h" /* Data filters */
#include "H5VLpublic.h" /* VOL plugins */
/* Predefined VOL plugins */
#include "H5VLnative.h" /* Native HDF5 plugin */
+#include "H5VLiod.h" /* IOD VOL plugin */
/* Predefined file drivers */
#include "H5FDcore.h" /* Files stored entirely in memory */
diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in
index b594cc2..ab7d8a9 100644
--- a/src/libhdf5.settings.in
+++ b/src/libhdf5.settings.in
@@ -57,6 +57,7 @@ Languages:
Features:
---------
Parallel HDF5: @PARALLEL@
+ Exascale Fast Forward Stack: @EFF@
High Level library: @HDF5_HL@
Threadsafety: @THREADSAFE@
Default API Mapping: @DEFAULT_API_VERSION@