diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-07-12 21:07:03 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2013-07-12 21:07:03 (GMT) |
commit | f2a2ef446e0503d232f24270e78c91e7ba40fdfc (patch) | |
tree | 71ccdef0400e5f7fedecaeeb970f0d48b47e57e0 | |
parent | 46b5d073b56090829f6f6519553b4a427703e129 (diff) | |
download | hdf5-f2a2ef446e0503d232f24270e78c91e7ba40fdfc.zip hdf5-f2a2ef446e0503d232f24270e78c91e7ba40fdfc.tar.gz hdf5-f2a2ef446e0503d232f24270e78c91e7ba40fdfc.tar.bz2 |
[svn-r23893] Add New HDF5 object - Map
Add the IOD VOL implementation. Not supported with native plugin.
Add example program to sanity check the API Forwarding
-rw-r--r-- | examples/Makefile.am | 2 | ||||
-rw-r--r-- | examples/Makefile.in | 2 | ||||
-rw-r--r-- | examples/test_client_acg.c | 76 | ||||
-rw-r--r-- | examples/test_client_old_api.c | 1 | ||||
-rw-r--r-- | examples/test_map.c | 187 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/H5.c | 1 | ||||
-rw-r--r-- | src/H5FF.c | 2 | ||||
-rw-r--r-- | src/H5Ipublic.h | 1 | ||||
-rw-r--r-- | src/H5M.c | 907 | ||||
-rw-r--r-- | src/H5Mpublic.h | 74 | ||||
-rw-r--r-- | src/H5VLiod.c | 973 | ||||
-rw-r--r-- | src/H5VLiod_client.c | 133 | ||||
-rw-r--r-- | src/H5VLiod_client.h | 50 | ||||
-rw-r--r-- | src/H5VLiod_common.h | 44 | ||||
-rw-r--r-- | src/H5VLiod_dset.c | 6 | ||||
-rw-r--r-- | src/H5VLiod_encdec.c | 78 | ||||
-rw-r--r-- | src/H5VLiod_map.c | 851 | ||||
-rw-r--r-- | src/H5VLiod_server.c | 458 | ||||
-rw-r--r-- | src/H5VLiod_server.h | 40 | ||||
-rw-r--r-- | src/H5private.h | 1 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/Makefile.in | 19 |
23 files changed, 3818 insertions, 98 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index 096c9fc..127d0bf 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -30,7 +30,7 @@ endif if BUILD_EFF_CONDITIONAL INCLUDES=-I$(top_srcdir)/src -I$(top_srcdir)/test LDADD = $(LIBH5TEST) $(LIBHDF5) $(MYAXE_LIBS) $(MYIOD_LIBS) - EXAMPLE_PROG_EFF = test_server test_client test_client_old_api test_client_acg + EXAMPLE_PROG_EFF = test_server test_client test_map test_client_old_api test_client_acg endif # Example programs. diff --git a/examples/Makefile.in b/examples/Makefile.in index 47dc829..609b3aa 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -401,7 +401,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog $(EXTLINK_DIRS) *.h5 @BUILD_EFF_CONDITIONAL_TRUE@LDADD = $(LIBH5TEST) $(LIBHDF5) $(MYAXE_LIBS) $(MYIOD_LIBS) @BUILD_PARALLEL_CONDITIONAL_TRUE@LDADD = $(LIBH5TEST) $(LIBHDF5) @BUILD_PARALLEL_CONDITIONAL_TRUE@EXAMPLE_PROG_PARA = ph5example -@BUILD_EFF_CONDITIONAL_TRUE@EXAMPLE_PROG_EFF = test_server test_client test_client_old_api test_client_acg +@BUILD_EFF_CONDITIONAL_TRUE@EXAMPLE_PROG_EFF = test_server test_client test_map test_client_old_api test_client_acg # Example programs. # Don't tell automake about them, because if it knew they were programs, diff --git a/examples/test_client_acg.c b/examples/test_client_acg.c index c22517f..c4b2340 100644 --- a/examples/test_client_acg.c +++ b/examples/test_client_acg.c @@ -68,81 +68,6 @@ int main(int argc, char **argv) { file_id = H5Fcreate_ff(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, event_q);
assert(file_id);
-#if 0
- {
- int r_data[60], r2_data[60];
- hid_t did1;
- unsigned read1_cs, read2_cs, cs=448091133;
-
-
- /* create a dataspace. This is a local Bookeeping operation that
- does not touch the file */
- dim = 60;
- sid = H5Screate_simple(1, &dim, NULL);
-
- did1 = H5Dcreate_ff(file_id,"D1",H5T_STD_I32LE,sid,
- H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, event_q);
- assert(did1);
-
- dxpl_id = H5Pcreate (H5P_DATASET_XFER);
- H5Pset_dxpl_checksum_ptr(dxpl_id, &read1_cs);
- ret = H5Dread_ff(did1, H5T_STD_I32LE, sid, sid, dxpl_id, r_data,
- 0, event_q);
- assert(ret == 0);
- H5Pclose(dxpl_id);
-
- /*
- if(H5EQpop(event_q, &req1) < 0)
- exit(1);
- assert(H5AOtest(req1, &status1) == 0);
- (status1 == H5AO_PENDING) ? fprintf(stderr, "Read is still pending\n") : fprintf(stderr, "Read has completed\n");
- */
-
- dxpl_id = H5Pcreate (H5P_DATASET_XFER);
- H5Pset_dxpl_inject_corruption(dxpl_id, 1);
- H5Pset_dxpl_checksum_ptr(dxpl_id, &read2_cs);
- ret = H5Dread_ff(did1, H5T_STD_I32LE, sid, sid, dxpl_id, r2_data,
- 0, event_q);
- assert(ret == 0);
- H5Pclose(dxpl_id);
-
- if(H5EQpop(event_q, &req1) < 0)
- exit(1);
- assert(H5AOtest(req1, &status1) == 0);
- (status1 == H5AO_PENDING) ? fprintf(stderr, "Read is still pending\n") : fprintf(stderr, "Read has completed\n");
-
- if(H5AO_PENDING == status1) {
- assert(H5AOwait(req1, &status1) == 0);
- assert (status1);
- }
- else
- assert(H5AO_SUCCEEDED == status1);
-
- assert(H5Dclose_ff(did1, event_q) == 0);
- assert(H5Fclose_ff(file_id, event_q) == 0);
-
- H5EQwait(event_q, &num_requests, &status);
-
- fprintf(stderr, "Printing After Waiting ");
- for(i=0;i<60;++i)
- fprintf(stderr, "%d ",r_data[i]);
- fprintf(stderr, "\n");
- fprintf(stderr, "Checksum Receieved = %u Checksum Computed = %u (Should be Equal)\n", read1_cs, cs);
-
- fprintf(stderr, "Printing Corrupted Data ");
- for(i=0;i<60;++i)
- fprintf(stderr, "%d ",r2_data[i]);
- fprintf(stderr, "\n");
- fprintf(stderr, "Checksum Receieved = %u Checksum Computed = %u (Should NOT be Equal)\n", read2_cs, cs);
-
- assert(read1_cs == cs);
- assert(read2_cs != cs);
-
- H5Sclose(sid);
- }
-#endif
-
-#if 1
/* Create 1-D dataspace */
dim = 0;
max_dim = H5S_UNLIMITED;
@@ -221,7 +146,6 @@ int main(int argc, char **argv) { for(u = 0; u < 60; u++)
if(read_elem[u] != write_elem[u])
return 1;
-#endif
fprintf(stderr, "\n*****************************************************************************************************************\n");
fprintf(stderr, "Finalize EFF stack\n");
diff --git a/examples/test_client_old_api.c b/examples/test_client_old_api.c index b943539..8262690 100644 --- a/examples/test_client_old_api.c +++ b/examples/test_client_old_api.c @@ -284,4 +284,3 @@ int main(int argc, char **argv) { MPI_Finalize();
return 0;
}
-
diff --git a/examples/test_map.c b/examples/test_map.c new file mode 100644 index 0000000..59228f1 --- /dev/null +++ b/examples/test_map.c @@ -0,0 +1,187 @@ +/*
+ * test_client_acg.c: Client side of Map Object
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "mpi.h"
+#include "hdf5.h"
+
+int main(int argc, char **argv) {
+ const char file_name[]="map_file.h5";
+ hid_t file_id;
+ hid_t gid1, gid2;
+ hid_t map1, map2, map3;
+ hid_t fapl_id, dxpl_id;
+ int my_rank, my_size;
+ int provided;
+ hid_t event_q;
+ H5_status_t *status = NULL;
+ int num_requests = 0, i;
+ herr_t ret;
+ hsize_t count = -1;
+ int key, value;
+ hbool_t exists = -1;
+ H5_request_t req1;
+ H5_status_t status1;
+
+ MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
+ if(MPI_THREAD_MULTIPLE != provided) {
+ fprintf(stderr, "MPI does not have MPI_THREAD_MULTIPLE support\n");
+ exit(1);
+ }
+
+ /* Call EFF_init to initialize the EFF stack.
+ As a result of this call, the Function Shipper client is started,
+ and HDF5 VOL calls are registered with the function shipper.
+ An "IOD init" call is forwarded from the FS client to the FS server
+ which should already be running. */
+ EFF_init(MPI_COMM_WORLD, MPI_INFO_NULL);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &my_size);
+ fprintf(stderr, "APP processes = %d, my rank is %d\n", my_size, my_rank);
+
+ fprintf(stderr, "Create the FAPL to set the IOD VOL plugin and create the file\n");
+ /* Choose the IOD VOL plugin to use with this file.
+ First we create a file access property list. Then we call a new routine to set
+ the IOD plugin to use with this fapl */
+ fapl_id = H5Pcreate (H5P_FILE_ACCESS);
+ H5Pset_fapl_iod(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL);
+
+ /* create an event Queue for managing asynchronous requests.
+
+ Event Queues will releive the use from managing and completing
+ individual requests for every operation. Instead of passing a
+ request for every operation, the event queue is passed and
+ internally the HDF5 library creates a request and adds it to
+ the event queue.
+
+ Multiple Event queue can be created used by the application. */
+ event_q = H5EQcreate(fapl_id);
+ assert(event_q);
+
+ /* create the file. This is asynchronous, but the file_id can be used. */
+ file_id = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+ assert(file_id);
+
+ /* create two groups */
+ gid1 = H5Gcreate_ff(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, (uint64_t)0, event_q);
+ gid2 = H5Gcreate_ff(file_id, "G1/G2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, (uint64_t)0, event_q);
+
+ /* Create Map objects with the key type and val type being 32 bit
+ LE integers */
+ map1 = H5Mcreate_ff(file_id, "MAP_1", H5T_STD_I32LE, H5T_STD_I32LE,
+ H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, (uint64_t)0, event_q);
+ map2 = H5Mcreate_ff(gid1, "MAP_2", H5T_STD_I32LE, H5T_STD_I32LE,
+ H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, (uint64_t)0, event_q);
+ map3 = H5Mcreate_ff(file_id, "G1/G2/MAP_3", H5T_STD_I32LE, H5T_STD_I32LE,
+ H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, (uint64_t)0, event_q);
+
+ {
+ key = 1;
+ value = 1000;
+ ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
+ H5P_DEFAULT, (uint64_t)0, event_q);
+ assert(ret == 0);
+
+ key = 2;
+ value = 2000;
+ ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
+ H5P_DEFAULT, (uint64_t)0, event_q);
+ assert(ret == 0);
+
+ key = 3;
+ value = 3000;
+ ret = H5Mset_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
+ H5P_DEFAULT, (uint64_t)0, event_q);
+ assert(ret == 0);
+ }
+
+ ret = H5Mget_count_ff(map3, &count, (uint64_t)0, event_q);
+ assert(ret == 0);
+
+ key = 1;
+ ret = H5Mexists_ff(map3, H5T_STD_I32LE, &key, &exists, (uint64_t)0, event_q);
+ assert(ret == 0);
+
+ key = 1;
+ ret = H5Mdelete_ff(map3, H5T_STD_I32LE, &key, (uint64_t)0, event_q);
+ assert(ret == 0);
+
+ assert(H5Gclose_ff(gid1, event_q) == 0);
+ assert(H5Gclose_ff(gid2, event_q) == 0);
+ assert(H5Mclose_ff(map1, event_q) == 0);
+ assert(H5Mclose_ff(map2, event_q) == 0);
+ assert(H5Mclose_ff(map3, event_q) == 0);
+
+ map3 = H5Mopen_ff(file_id, "G1/G2/MAP_3", H5P_DEFAULT, (uint64_t)0, event_q);
+
+ {
+ int key, value;
+
+ key = 1;
+ value = -1;
+ ret = H5Mget_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
+ H5P_DEFAULT, (uint64_t)0, event_q);
+
+ if(H5EQpop(event_q, &req1) < 0)
+ exit(1);
+ assert(H5AOwait(req1, &status1) == 0);
+ assert (status1);
+ printf("Value recieved == %d\n", value);
+ /* this is the fake value we sent from the server */
+ assert(value == 1024);
+
+ key = 1;
+ value = -1;
+ ret = H5Mget_ff(map3, H5T_STD_I32LE, &key, H5T_STD_I32LE, &value,
+ H5P_DEFAULT, (uint64_t)0, event_q);
+
+ if(H5EQpop(event_q, &req1) < 0)
+ exit(1);
+ assert(H5AOwait(req1, &status1) == 0);
+ assert (status1);
+
+ /* this is the fake value we sent from the server */
+ assert(value == 1024);
+ }
+
+ assert(H5Mclose_ff(map3, event_q) == 0);
+
+ /* closing the container also acts as a wait all on all pending requests
+ on the container. */
+ assert(H5Fclose_ff(file_id, event_q) == 0);
+
+ fprintf(stderr, "\n*****************************************************************************************************************\n");
+ fprintf(stderr, "Wait on everything in EQ and check Results of operations in EQ\n");
+ fprintf(stderr, "*****************************************************************************************************************\n");
+
+ /* wait on all requests and print completion status */
+ H5EQwait(event_q, &num_requests, &status);
+ fprintf(stderr, "%d requests in event queue. Completions: ", num_requests);
+ for(i=0 ; i<num_requests; i++)
+ fprintf(stderr, "%d ",status[i]);
+ fprintf(stderr, "\n");
+ free(status);
+
+ assert (count == 3);
+ assert (exists > 0);
+
+ fprintf(stderr, "\n*****************************************************************************************************************\n");
+ fprintf(stderr, "Finalize EFF stack\n");
+ fprintf(stderr, "*****************************************************************************************************************\n");
+
+ H5EQclose(event_q);
+ H5Pclose(fapl_id);
+
+ /* This finalizes the EFF stack. ships a terminate and IOD finalize to the server
+ and shutsdown the FS server (when all clients send the terminate request)
+ and client */
+ EFF_finalize();
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ddc1cd3..6b8137a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -627,10 +627,12 @@ SET (H5VL_HDRS IF (HDF5_ENABLE_EFF) SET (H5FF_SRCS ${HDF5_SRC_DIR}/H5FF.c + ${HDF5_SRC_DIR}/H5M.c ${HDF5_SRC_DIR}/H5EQ.c ) SET (H5FF_HDRS ${HDF5_SRC_DIR}/H5FFpublic.h + ${HDF5_SRC_DIR}/H5Mpublic.h ${HDF5_SRC_DIR}/H5EQpublic.h ) IDE_GENERATED_PROPERTIES ("H5FF" "${H5FF_HDRS}" "${H5FF_SRCS}" ) @@ -646,6 +648,7 @@ IF (HDF5_ENABLE_EFF) ${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_encdec.c ) SET (H5VL_HDRS @@ -255,6 +255,7 @@ H5_term_library(void) pending += DOWN(D); pending += DOWN(L); pending += DOWN(G); + pending += DOWN(M); pending += DOWN(A); pending += DOWN(S); pending += DOWN(T); @@ -548,7 +548,7 @@ H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - + printf("EQ ID is %d\n", eq_id); if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index aa216bf..02693f0 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -38,6 +38,7 @@ typedef enum H5I_type_t { H5I_BADID = (-1), /*invalid Type */ H5I_FILE = 1, /*type ID for File objects */ H5I_GROUP, /*type ID for Group objects */ + H5I_MAP, /*type ID for MAP objects */ H5I_DATATYPE, /*type ID for Datatype objects */ H5I_DATASPACE, /*type ID for Dataspace objects */ H5I_DATASET, /*type ID for Dataset objects */ diff --git a/src/H5M.c b/src/H5M.c new file mode 100644 index 0000000..11a9e9b --- /dev/null +++ b/src/H5M.c @@ -0,0 +1,907 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 "H5EQprivate.h" /* Event Queues */ +#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 */ + +/****************/ +/* 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 */ + 64, /* Minimum hash size for class */ + 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, uint64_t trans, hid_t eq_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) + + /* 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") + + 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* 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, 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) { + H5EQ_t *eq = NULL; /* event queue token */ + + /* get the eq object */ + if(NULL == (eq = (H5EQ_t *)H5I_object_verify(eq_id, H5I_EQ))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event queue identifier") + + if(H5EQ_insert(eq, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue") + } + + /* 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, uint64_t trans, hid_t eq_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) + + /* Check arguments */ + 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); + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* call the IOD specific private routine to create a map object */ + if(NULL == (map = H5VL_iod_map_open(obj, loc_params, name, mapl_id, trans, 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(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue") + } + + /* 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, uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* 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, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set map KV pair") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + +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, uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* 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, trans, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + +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, + uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* Get the data through the IOD VOL */ + if((ret_value = H5VL_iod_map_get_types(map, key_type_id, val_type_id, trans, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + +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, uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* Get the data through the IOD VOL */ + if((ret_value = H5VL_iod_map_get_count(map, count, trans, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + +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, + htri_t *exists, uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* Get the data through the IOD VOL */ + if((ret_value = H5VL_iod_map_exists(map, key_mem_type_id, key, exists, trans, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mexists_ff */ + + +/*------------------------------------------------------------------------- + * Function: H5Miterate + * + * 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(hid_t map_id, hid_t key_mem_type_id, hid_t value_mem_type_id, + H5M_iterate_func_t callback_func, void *context) +{ + void *map = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + +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, + uint64_t trans, hid_t eq_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) + + /* 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(eq_id != H5_EVENT_QUEUE_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; + } + + /* delete the key pair through the IOD VOL */ + if((ret_value = H5VL_iod_map_delete(map, key_mem_type_id, key, trans, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value") + + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } +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 eq_id) +{ + H5VL_t *vol_plugin = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* 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_eq_id = eq_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_eq_id != H5_EVENT_QUEUE_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; + } + + /* 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(H5EQinsert(vol_plugin->close_eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + + 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() */ diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h new file mode 100644 index 0000000..78b2fdf --- /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, uint64_t trans, hid_t eq_id); +H5_DLL hid_t H5Mopen_ff(hid_t loc_id, const char *name, hid_t mapl_id, uint64_t trans, hid_t eq_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, uint64_t trans, hid_t eq_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, uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Mget_types_ff(hid_t map_id, hid_t *key_type_id, hid_t *val_type_id, + uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Mget_count_ff(hid_t map_id, hsize_t *count, uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Mexists_ff(hid_t map_id, hid_t key_mem_type_id, const void *key, + htri_t *exists, uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Miterate(hid_t map_id, hid_t key_mem_type_id, hid_t value_mem_type_id, + H5M_iterate_func_t callback_func, void *context); +H5_DLL herr_t H5Mdelete_ff(hid_t map_id, hid_t key_mem_type_id, const void *key, + uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Mclose_ff(hid_t map_id, hid_t eq_id); + +#ifdef __cplusplus +} +#endif +#endif /* _H5Mpublic_H */ diff --git a/src/H5VLiod.c b/src/H5VLiod.c index 6855ca1..ee2bb91 100644 --- a/src/H5VLiod.c +++ b/src/H5VLiod.c @@ -49,12 +49,22 @@ 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; @@ -157,6 +167,7 @@ typedef struct 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); @@ -355,6 +366,7 @@ EFF_init(MPI_Comm comm, MPI_Info UNUSED info) 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); @@ -363,6 +375,16 @@ EFF_init(MPI_Comm comm, MPI_Info UNUSED info) 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); @@ -6322,4 +6344,955 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_wait() */ +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, uint64_t trans, 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_handle_t iod_oh; + uint64_t parent_axe_id; + char *new_name = NULL; /* resolved path to where we need to start traversal at the server */ + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Retrieve the parent AXE id by traversing the path where the + map should be created. */ + if(H5VL_iod_get_parent_info(obj, loc_params, name, &iod_id, &iod_oh, + &parent_axe_id, &new_name, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current working group"); + + /* 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.cookie = IOD_OH_UNDEFINED; + map->remote_map.iod_id = IOD_ID_UNDEFINED; + + /* Generate an IOD ID 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.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 ++; + + /* 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.parent_axe_id = parent_axe_id; + input.name = new_name; + input.keytype_id = keytype; + input.valtype_id = valtype; + input.axe_id = axe_id ++; + +#if H5VL_IOD_DEBUG + printf("Map Create %s, IOD ID %llu, axe id %llu, parent %llu\n", + new_name, input.map_id, input.axe_id, input.parent_axe_id); +#endif + + /* get a function shipper request */ + if(do_async) { + if(NULL == (hg_req = (hg_request_t *)H5MM_malloc(sizeof(hg_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate a HG request"); + } /* end if */ + else + hg_req = &_hg_req; + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_CREATE_ID, &input, &map->remote_map, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship map create"); + + /* setup the local map struct */ + /* store the entire path of the map locally */ + { + 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'; + } + + 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 ++; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_CREATE; + request->data = map; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + map->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't wait on HG request") + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + map->common.request = NULL; + } /* end else */ + + ret_value = (void *)map; + +done: + if(new_name) free(new_name); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_iod_map_create() */ + +void * +H5VL_iod_map_open(void *_obj, H5VL_loc_params_t loc_params, const char *name, hid_t mapl_id, + uint64_t trans, 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_handle_t iod_oh; + uint64_t parent_axe_id; + char *new_name = NULL; /* resolved path to where we need to start traversal at the server */ + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Retrieve the parent AXE id by traversing the path where the + map should be created. */ + if(H5VL_iod_get_parent_info(obj, loc_params, name, &iod_id, &iod_oh, + &parent_axe_id, &new_name, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "Failed to resolve current working group"); + + /* 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.cookie = IOD_OH_UNDEFINED; + map->remote_map.iod_id = IOD_ID_UNDEFINED; + 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.parent_axe_id = parent_axe_id; + input.name = new_name; + input.axe_id = axe_id ++; + +#if H5VL_IOD_DEBUG + printf("Map Open %s LOC ID %llu, axe id %llu, parent %llu, name len %zu\n", + new_name, input.loc_id, input.axe_id, input.parent_axe_id, strlen(input.name)); +#endif + + /* get a function shipper request */ + if(do_async) { + if(NULL == (hg_req = (hg_request_t *)H5MM_malloc(sizeof(hg_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate a HG request"); + } /* end if */ + else + hg_req = &_hg_req; + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_OPEN_ID, &input, &map->remote_map, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship map create"); + + /* setup the local map struct */ + /* store the entire path of the map locally */ + { + 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'; + } + + /* set common object parameters */ + map->common.obj_type = H5I_MAP; + map->common.file = obj->file; + map->common.file->nopen_objs ++; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_OPEN; + request->data = map; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + map->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't wait on HG request") + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + map->common.request = NULL; + } /* end else */ + + ret_value = (void *)map; + +done: + if(new_name) free(new_name); + 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, + uint64_t trans, 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; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + 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; + } + + /* set the parent axe id */ + if(map->common.request) + input.parent_axe_id = map->common.request->axe_id; + else { + input.parent_axe_id = 0; + } + + /* get the Key and Value size */ + { + H5T_t *dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(key_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + key_size = H5T_GET_SIZE(dt); + + dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(val_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + val_size = H5T_GET_SIZE(dt); + } + + /* 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.buf_size = val_size; + input.val.buf = value; + input.axe_id = axe_id ++; + + status = (int *)malloc(sizeof(int)); + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + + printf("kmap %d kmem %d. vmap %d kmap %d dxpl %d\n", + input.key_maptype_id,input.key_memtype_id,input.val_maptype_id,input.val_memtype_id, dxpl_id); + +#if H5VL_IOD_DEBUG + printf("MAP set, axe id %llu, parent %llu\n", + input.axe_id, input.parent_axe_id); +#endif + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_SET_ID, &input, status, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship map set"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_SET; + request->data = status; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + } /* end else */ + +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, + uint64_t trans, void **req) +{ + H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map; + map_get_in_t input; + map_get_out_t *output; + size_t key_size, val_size; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + 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; + } + + /* set the parent axe id */ + if(map->common.request) + input.parent_axe_id = map->common.request->axe_id; + else { + input.parent_axe_id = 0; + } + + /* get the Key and Value size */ + { + H5T_t *dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(key_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + key_size = H5T_GET_SIZE(dt); + + dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(val_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + val_size = H5T_GET_SIZE(dt); + } + + /* 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.val_maptype_id = map->remote_map.valtype_id; + input.key_memtype_id = key_mem_type_id; + input.key.buf_size = key_size; + input.key.buf = key; + input.val_memtype_id = val_mem_type_id; + input.axe_id = axe_id ++; + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + +#if H5VL_IOD_DEBUG + printf("MAP Get, axe id %llu, parent %llu\n", + input.axe_id, input.parent_axe_id); +#endif + + if(NULL == (output = (map_get_out_t *)H5MM_calloc(sizeof(map_get_out_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate a request"); + + output->val.val = value; + output->val.val_size = val_size; + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_GET_ID, &input, output, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset read"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_GET; + request->data = output; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->status = 0; + request->state = 0; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + } /* end else */ +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, + uint64_t trans, void **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, uint64_t trans, void **req) +{ + H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map; + map_get_count_in_t input; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* set the parent axe id */ + if(map->common.request) + input.parent_axe_id = map->common.request->axe_id; + else { + input.parent_axe_id = 0; + } + + /* 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.axe_id = axe_id ++; + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + +#if H5VL_IOD_DEBUG + printf("MAP Get count, axe id %llu, parent %llu\n", + input.axe_id, input.parent_axe_id); +#endif + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_GET_COUNT_ID, &input, count, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset read"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_GET_COUNT; + request->data = count; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->status = 0; + request->state = 0; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + } /* end else */ + +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, + htri_t *exists, uint64_t trans, void **req) +{ + H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map; + map_op_in_t input; + size_t key_size; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* set the parent axe id */ + if(map->common.request) + input.parent_axe_id = map->common.request->axe_id; + else { + input.parent_axe_id = 0; + } + + /* get the Key and Value size */ + { + H5T_t *dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(key_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + key_size = H5T_GET_SIZE(dt); + } + + /* 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.axe_id = axe_id ++; + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + +#if H5VL_IOD_DEBUG + printf("MAP EXISTS, axe id %llu, parent %llu\n", + input.axe_id, input.parent_axe_id); +#endif + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_EXISTS_ID, &input, exists, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset read"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_EXISTS; + request->data = exists; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->status = 0; + request->state = 0; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_iod_map_exists() */ + +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) +{ + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_iod_map_iterate() */ + +herr_t +H5VL_iod_map_delete(void *_map, hid_t key_mem_type_id, const void *key, + uint64_t trans, void **req) +{ + H5VL_iod_map_t *map = (H5VL_iod_map_t *)_map; + map_op_in_t input; + size_t key_size; + int *status = NULL; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* set the parent axe id */ + if(map->common.request) + input.parent_axe_id = map->common.request->axe_id; + else { + input.parent_axe_id = 0; + } + + /* get the Key and Value size */ + { + H5T_t *dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object_verify(key_mem_type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype"); + key_size = H5T_GET_SIZE(dt); + } + + /* 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.axe_id = axe_id ++; + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + +#if H5VL_IOD_DEBUG + printf("MAP DELETE, axe id %llu, parent %llu\n", + input.axe_id, input.parent_axe_id); +#endif + + status = (int *)malloc(sizeof(int)); + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_DELETE_ID, &input, status, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset read"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_DELETE; + request->data = status; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->status = 0; + request->state = 0; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + map->common.request = request; + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + } /* end else */ + +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; + size_t num_parents; + uint64_t *axe_parents = NULL; + hg_request_t _hg_req; /* Local function shipper request, for sync. operations */ + hg_request_t *hg_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ + 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(!do_async) { + 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"); + } + + /* determine the parent axe IDs array for this operation*/ + if(H5VL_iod_get_axe_parents((H5VL_iod_object_t *)map, &num_parents, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get num AXE parents"); + if(num_parents) { + if(NULL == (axe_parents = (uint64_t *)H5MM_malloc(sizeof(uint64_t) * num_parents))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate num parents array"); + if(H5VL_iod_get_axe_parents((H5VL_iod_object_t *)map, &num_parents, axe_parents) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get AXE parents"); + } + + status = (int *)malloc(sizeof(int)); + + /* get a function shipper request */ + if(do_async) { + 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"); + } /* end if */ + else + hg_req = &_hg_req; + + input.iod_oh = map->remote_map.iod_oh; + input.iod_id = map->remote_map.iod_id; + input.parent_axe_ids.count = num_parents; + input.parent_axe_ids.ids = axe_parents; + input.axe_id = axe_id ++; + + /* forward the call to the IONs */ + if(HG_Forward(PEER, H5VL_MAP_CLOSE_ID, &input, status, hg_req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship map close"); + + /* Get async request for operation */ + if(do_async) { + 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"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = HG_MAP_CLOSE; + request->data = status; + request->req = hg_req; + request->obj = (H5VL_iod_object_t *)map; + request->axe_id = input.axe_id; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(map->common.file, request); + +#if H5VL_IOD_DEBUG + printf("MAP Close IOD ID %llu, axe id %llu\n", + input.iod_id, input.axe_id); +#endif + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + map->common.request = request; + } /* end if */ + else { + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(map->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on HG request"); + + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_iod_map_close() */ + #endif /* H5_HAVE_EFF */ diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c index 66825dc..b604d60 100644 --- a/src/H5VLiod_client.c +++ b/src/H5VLiod_client.c @@ -307,6 +307,20 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) H5VL_iod_request_delete(file, req); break; } + case HG_MAP_CREATE: + case HG_MAP_OPEN: + { + H5VL_iod_map_t *map = (H5VL_iod_map_t *)req->obj; + + if(IOD_OH_UNDEFINED == map->remote_map.iod_oh.cookie) { + fprintf(stderr, "failed to create/open Map\n"); + req->status = H5AO_FAILED; + req->state = H5VL_IOD_COMPLETED; + } + + H5VL_iod_request_delete(file, req); + break; + } case HG_DSET_CREATE: case HG_DSET_OPEN: { @@ -415,6 +429,64 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) H5VL_iod_request_delete(file, req); break; } + case HG_MAP_SET: + { + int *status = (int *)req->data; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "MAP set failed at the server"); + + free(status); + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case HG_MAP_DELETE: + { + int *status = (int *)req->data; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "MAP delete failed at the server"); + + free(status); + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case HG_MAP_GET: + { + map_get_out_t *output = (map_get_out_t *)req->data; + + if(SUCCEED != output->ret) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "MAP get failed at the server"); + + free(output); + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case HG_MAP_GET_COUNT: + { + hsize_t *count = (hsize_t *)req->data; + + if(*count < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "MAP get_count failed at the server"); + + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case HG_MAP_EXISTS: + { + htri_t *exists = (hbool_t *)req->data; + + if(*exists < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "MAP exists failed at the server"); + + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } case HG_FILE_FLUSH: { int *status = (int *)req->data; @@ -595,6 +667,30 @@ H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *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(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "map close failed at the server"); + + free(status); + req->data = NULL; + map->common.request = NULL; + H5VL_iod_request_delete(file, req); + + /* free map components */ + 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; @@ -747,6 +843,8 @@ H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req) case HG_ATTR_EXISTS: case HG_LINK_EXISTS: case HG_OBJECT_EXISTS: + case HG_MAP_GET_COUNT: + case HG_MAP_EXISTS: { H5VL_iod_object_t *obj = (H5VL_iod_object_t *)req->obj; @@ -857,6 +955,29 @@ H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req) 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 */ + 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: @@ -886,6 +1007,18 @@ H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req) 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: + case HG_MAP_DELETE: case HG_LINK_CREATE: case HG_LINK_MOVE: case HG_LINK_REMOVE: diff --git a/src/H5VLiod_client.h b/src/H5VLiod_client.h index 1943b0a..382f4bf 100644 --- a/src/H5VLiod_client.h +++ b/src/H5VLiod_client.h @@ -20,6 +20,7 @@ #define _H5VLiod_client_H #include "H5FFprivate.h" /* FastForward wrappers */ +#include "H5Mpublic.h" #include "H5VLiod_common.h" #ifdef H5_HAVE_EFF @@ -59,6 +60,15 @@ typedef enum H5RQ_type_t { HG_LINK_ITERATE, HG_LINK_EXISTS, 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, HG_OBJECT_COPY, HG_OBJECT_VISIT, @@ -110,6 +120,15 @@ typedef struct H5VL_iod_remote_group_t { 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_handle_t iod_oh; + iod_obj_id_t iod_id; + hid_t keytype_id; + hid_t valtype_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 */ @@ -177,6 +196,12 @@ typedef struct H5VL_iod_group_t { 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; +} H5VL_iod_map_t; + /* the client side dataset struct */ typedef struct H5VL_iod_dset_t { H5VL_iod_object_t common; /* must be first */ @@ -215,5 +240,30 @@ H5_DLL herr_t H5VL_iod_get_parent_info(H5VL_iod_object_t *obj, H5VL_loc_params_t H5_DLL herr_t H5VL_iod_get_axe_parents(H5VL_iod_object_t *obj, size_t *count, uint64_t *parents); 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); + +/* 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, uint64_t trans, void **req); +H5_DLL void *H5VL_iod_map_open(void *obj, H5VL_loc_params_t loc_params, + const char *name, hid_t mapl_id, uint64_t trans, 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, + uint64_t trans, 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, + uint64_t trans, void **req); +H5_DLL herr_t H5VL_iod_map_get_types(void *map, hid_t *key_type_id, hid_t *val_type_id, + uint64_t trans, void **req); +H5_DLL herr_t H5VL_iod_map_get_count(void *map, hsize_t *count, uint64_t trans, void **req); +H5_DLL herr_t H5VL_iod_map_exists(void *map, hid_t key_mem_type_id, const void *key, + htri_t *exists, uint64_t trans, 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, + uint64_t trans, void **req); +H5_DLL herr_t H5VL_iod_map_close(void *map, void **req); + #endif /* H5_HAVE_EFF */ #endif /* _H5VLiod_client_H */ diff --git a/src/H5VLiod_common.h b/src/H5VLiod_common.h index 92cb3eb..41adb68 100644 --- a/src/H5VLiod_common.h +++ b/src/H5VLiod_common.h @@ -48,7 +48,7 @@ typedef struct H5VL_iod_read_status_t { typedef struct dims_t { int rank; - const hsize_t *size; + hsize_t *size; } dims_t; typedef struct name_t { @@ -57,6 +57,16 @@ typedef struct name_t { 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; + H5_DLL int hg_proc_ret_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); @@ -66,6 +76,7 @@ H5_DLL int hg_proc_iod_handle_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_binary_buf_t(hg_proc_t proc, void *data); MERCURY_GEN_PROC(eff_init_in_t, ((uint32_t)(proc_num))) @@ -123,6 +134,37 @@ MERCURY_GEN_PROC(group_open_out_t, ((iod_handle_t)(iod_oh)) ((iod_obj_id_t)(iod_ MERCURY_GEN_PROC(group_close_in_t, ((iod_handle_t)(iod_oh)) ((iod_obj_id_t)(iod_id)) ((uint64_t)(parent_axe_id)) ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_create_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(loc_oh)) + ((iod_obj_id_t)(loc_id)) ((iod_obj_id_t)(map_id)) + ((uint64_t)(parent_axe_id)) ((hg_string_t)(name)) + ((hid_t)(keytype_id)) ((hid_t)(valtype_id)) ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_create_out_t, ((iod_handle_t)(iod_oh))) +MERCURY_GEN_PROC(map_open_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(loc_oh)) + ((iod_obj_id_t)(loc_id)) ((uint64_t)(parent_axe_id)) + ((hg_string_t)(name)) ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_open_out_t, ((iod_handle_t)(iod_oh)) ((iod_obj_id_t)(iod_id)) + ((hid_t)(keytype_id)) ((hid_t)(valtype_id))) +MERCURY_GEN_PROC(map_set_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(iod_oh)) + ((iod_obj_id_t)(iod_id)) ((uint64_t)(parent_axe_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)) ((binary_buf_t)(val)) + ((hid_t)(dxpl_id)) ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_get_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(iod_oh)) + ((iod_obj_id_t)(iod_id)) ((uint64_t)(parent_axe_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)) + ((hid_t)(dxpl_id)) ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_get_out_t, ((int32_t)(ret)) ((value_t)(val))) +MERCURY_GEN_PROC(map_get_count_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(iod_oh)) + ((iod_obj_id_t)(iod_id)) ((uint64_t)(parent_axe_id)) + ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_op_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(iod_oh)) + ((iod_obj_id_t)(iod_id)) ((uint64_t)(parent_axe_id)) + ((hid_t)(key_maptype_id)) ((hid_t)(key_memtype_id)) ((binary_buf_t)(key)) + ((uint64_t)(axe_id))) +MERCURY_GEN_PROC(map_close_in_t, ((iod_handle_t)(iod_oh)) ((iod_obj_id_t)(iod_id)) + ((axe_ids_t)(parent_axe_ids)) ((uint64_t)(axe_id))) + MERCURY_GEN_PROC(dset_create_in_t, ((iod_handle_t)(coh)) ((iod_handle_t)(loc_oh)) ((iod_obj_id_t)(loc_id)) ((iod_obj_id_t)(dset_id)) ((uint64_t)(parent_axe_id)) ((hg_string_t)(name)) diff --git a/src/H5VLiod_dset.c b/src/H5VLiod_dset.c index d20c693..1710d9c 100644 --- a/src/H5VLiod_dset.c +++ b/src/H5VLiod_dset.c @@ -619,7 +619,7 @@ done: /* close the dataset if we opened it in this routine */ if(opened_locally) { if(iod_obj_close(iod_oh, NULL, NULL)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object"); + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object"); } FUNC_LEAVE_NOAPI_VOID } /* end H5VL_iod_server_dset_read_cb() */ @@ -748,7 +748,7 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, int *ptr = (int *)buf; fprintf(stderr, "DWRITE Received a buffer of size %d with values: ", size); - for(i=0;i<60;++i) + for(i=0 ; i<size/sizeof(int) ; ++i) fprintf(stderr, "%d ", ptr[i]); fprintf(stderr, "\n"); } @@ -850,7 +850,7 @@ done: /* close the dataset if we opened it in this routine */ if(opened_locally) { if(iod_obj_close(iod_oh, NULL, NULL)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object"); + HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close Array object"); } FUNC_LEAVE_NOAPI_VOID } /* end H5VL_iod_server_dset_write_cb() */ diff --git a/src/H5VLiod_encdec.c b/src/H5VLiod_encdec.c index c342984..80cab90 100644 --- a/src/H5VLiod_encdec.c +++ b/src/H5VLiod_encdec.c @@ -207,7 +207,6 @@ int hg_proc_name_t(hg_proc_t proc, void *data) name_t *struct_data = (name_t *) data; ret = hg_proc_memcpy(proc, struct_data->value_size, sizeof(ssize_t)); - //ret = hg_proc_int64_t(proc, struct_data->value_size); if (ret != HG_SUCCESS) { HG_ERROR_DEFAULT("Proc error"); ret = HG_FAIL; @@ -216,7 +215,6 @@ int hg_proc_name_t(hg_proc_t proc, void *data) size = (size_t)(*struct_data->value_size); ret = hg_proc_memcpy(proc, &struct_data->size, sizeof(size_t)); - //ret = hg_proc_uint64_t(proc, &struct_data->size); if (ret != HG_SUCCESS) { HG_ERROR_DEFAULT("Proc error"); ret = HG_FAIL; @@ -235,6 +233,81 @@ int hg_proc_name_t(hg_proc_t proc, void *data) return ret; } +int hg_proc_binary_buf_t(hg_proc_t proc, void *data) +{ + int ret = HG_SUCCESS; + size_t size; + 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; + size_t size; + hg_proc_op_t op; + 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; +} + /* Define hg_proc_plist_t */ static int hg_proc_plist_t(hg_proc_t proc, hid_t *data) { @@ -325,7 +398,6 @@ static int hg_proc_plist_t(hg_proc_t proc, hid_t *data) default: HG_ERROR_DEFAULT("PLIST unsupported op Proc error"); } - return ret; } diff --git a/src/H5VLiod_map.c b/src/H5VLiod_map.c new file mode 100644 index 0000000..6511bf5 --- /dev/null +++ b/src/H5VLiod_map.c @@ -0,0 +1,851 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. + */ + +#define EEXISTS 1 + + +/*------------------------------------------------------------------------- + * 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_handle_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 */ + 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_handle_t map_oh, cur_oh, mdkv_oh; + iod_obj_id_t cur_id, mdkv_id; + char *last_comp; /* the name of the group obtained from traversal function */ + iod_kv_t kv; + scratch_pad_t sp; + iod_ret_t ret; + hbool_t collective = FALSE; /* MSC - change when we allow for collective */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start map create %s\n", name); +#endif + + /* 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, FALSE, + &last_comp, &cur_id, &cur_oh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path"); + + /* create the map */ + ret = iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &map_id, NULL); + if(collective && (0 == ret || EEXISTS == ret)) { + /* map has been created by another process, open it */ + if (iod_obj_open_write(coh, map_id, NULL, &map_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Map"); + } + else if(!collective && 0 != ret) { + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Map"); + } + + /* for the process that succeeded in creating the map, create + the scratch pad for it too */ + if(0 == ret) { + /* create the metadata KV object for the map */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &mdkv_id, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object"); + + /* set values for the scratch pad object */ + sp.mdkv_id = mdkv_id; + sp.attr_id = IOD_ID_UNDEFINED; + sp.filler1_id = IOD_ID_UNDEFINED; + sp.filler2_id = IOD_ID_UNDEFINED; + + /* set scratch pad in map */ + if (iod_obj_set_scratch(map_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad"); + + /* Store Metadata in scratch pad */ + if (iod_obj_open_write(coh, mdkv_id, NULL, &mdkv_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create scratch pad"); + + /* MSC - TODO store things */ + + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + + /* insert new map in kv store of parent object */ + kv.key = HDstrdup(last_comp); + kv.value = &map_id; + kv.value_len = sizeof(iod_obj_id_t); + if (iod_kv_set(cur_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + HDfree(kv.key); + } /* end if */ + + /* close parent group if it is not the location we started the + traversal into */ + if(loc_handle.cookie != cur_oh.cookie) { + iod_obj_close(cur_oh, NULL, NULL); + } + + +#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 = map_oh; + 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 Map Create\n"); + output.iod_oh.cookie = IOD_OH_UNDEFINED; + HG_Handler_start_output(op_data->hg_handle, &output); + } + + 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_handle_t loc_handle = input->loc_oh; + iod_obj_id_t loc_id = input->loc_id; + const char *name = input->name; + iod_obj_id_t map_id; /* The ID of the map that needs to be opened */ + iod_handle_t cur_oh, mdkv_oh; + iod_obj_id_t cur_id, mdkv_id; + char *last_comp; /* the name of the map obtained from traversal function */ + iod_size_t kv_size; + scratch_pad_t sp; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start map open %s\n", name); +#endif + + /* 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, FALSE, + &last_comp, &cur_id, &cur_oh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path"); + + kv_size = sizeof(iod_obj_id_t); + + /* lookup map in the current location */ + if(iod_kv_get_value(cur_oh, IOD_TID_UNKNOWN, last_comp, &map_id, + &kv_size, NULL, NULL) < 0) { + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Intermdiate group does not exist"); + } /* end if */ + + /* close parent group and its scratch pad if it is not the + location we started the traversal into */ + if(loc_handle.cookie != cur_oh.cookie) { + iod_obj_close(cur_oh, NULL, NULL); + } + + /* open the map */ + if (iod_obj_open_write(coh, map_id, NULL, &cur_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current map"); + + /* get scratch pad of map */ + if(iod_obj_get_scratch(cur_oh, IOD_TID_UNKNOWN, &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.mdkv_id, NULL /*hints*/, &mdkv_oh, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't open scratch pad"); + + /* MSC - retrieve metadata */ + + /* close the metadata scratch pad */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close meta data KV handle"); + + output.iod_id = map_id; + output.iod_oh = cur_oh; + + /* MSC - fake datatypes for now*/ + output.keytype_id = H5Tcopy(H5T_NATIVE_INT); + output.valtype_id = H5Tcopy(H5T_NATIVE_INT); + +#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.cookie = IOD_OH_UNDEFINED; + output.iod_id = IOD_ID_UNDEFINED; + HG_Handler_start_output(op_data->hg_handle, &output); + } + + H5Tclose(output.keytype_id); + H5Tclose(output.valtype_id); + + last_comp = (char *)H5MM_xfree(last_comp); + 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; + 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; + binary_buf_t val = input->val; + hid_t dxpl_id = input->dxpl_id; + iod_size_t key_size, val_size; + size_t src_size, dst_size; + void *key_buf = NULL, *val_buf = NULL; + iod_kv_t kv; + hbool_t opened_locally = FALSE; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start map set\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, NULL /*hints*/, &iod_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); + opened_locally = TRUE; + } + + /* Check (and do) Type conversion on the Key */ + src_size = H5Tget_size(key_memtype_id); + dst_size = H5Tget_size(key_maptype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size < dst_size) { + key_size = dst_size; + } + else { + key_size = src_size; + } + + if(NULL == (key_buf = malloc(key_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + memcpy(key_buf, key.buf, src_size); + + if(H5Tconvert(key_memtype_id, key_maptype_id, 1, key_buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed") + + /* Check (and do) Type conversion on the Value */ + src_size = H5Tget_size(val_memtype_id); + dst_size = H5Tget_size(val_maptype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size < dst_size) { + val_size = dst_size; + } + else { + val_size = src_size; + } + if(NULL == (val_buf = malloc(val_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + memcpy(val_buf, val.buf, src_size); + if(H5Tconvert(val_memtype_id, val_maptype_id, 1, val_buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed") + + + kv.key = key_buf; + kv.value = val_buf; + kv.value_len = (iod_size_t)val_size; + /* insert kv pair into scratch pad */ + if (iod_kv_set(iod_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +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"); + + if(key_buf) + free(key_buf); + if(val_buf) + free(val_buf); + + input = (map_set_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)) + HGOTO_ERROR(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; + 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_size_t key_size, val_size; + size_t src_size, dst_size; + void *key_buf = NULL, *val_buf = NULL; + hbool_t opened_locally = FALSE; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start map get \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, NULL /*hints*/, &iod_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); + opened_locally = TRUE; + } + + /* Check (and do) Type conversion on the Key */ + src_size = H5Tget_size(key_memtype_id); + dst_size = H5Tget_size(key_maptype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size < dst_size) { + key_size = dst_size; + } + else { + key_size = src_size; + } + + if(NULL == (key_buf = malloc(key_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + memcpy(key_buf, key.buf, src_size); + + if(H5Tconvert(key_memtype_id, key_maptype_id, 1, key_buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed") + + /* Check (and do) Type conversion on the Value */ + src_size = H5Tget_size(val_maptype_id); + dst_size = H5Tget_size(val_memtype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size > dst_size) { + val_size = src_size; + } + else { + val_size = dst_size; + } + + if(NULL == (val_buf = malloc(val_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + + if(iod_kv_get_value(iod_oh, IOD_TID_UNKNOWN, key_buf, val_buf, + &src_size, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve value from parent KV store"); + + /* MSC - Fake something for now */ + *((int *)val_buf) = 1024; + + if(H5Tconvert(val_maptype_id, val_memtype_id, 1, val_buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed") + + output.val.val_size = val_size; + output.val.val = val_buf; + output.ret = ret_value; + +#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_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get"); + +done: + + if(ret_value < 0) { + output.ret = FAIL; + output.val.val_size = 0; + output.val.val = NULL; + 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); + if(key_buf) + free(key_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)) + HGOTO_ERROR(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_Count a KV pair 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; + iod_obj_id_t iod_id = input->iod_id; + iod_size_t num; + 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_write(coh, iod_id, NULL /*hints*/, &iod_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); + opened_locally = TRUE; + } + + if(iod_kv_get_num(iod_oh, IOD_TID_UNKNOWN, &num, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Number of KV pairs in MAP"); + + /* MSC - fake something for now */ + num = 3; + +#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, &num)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't send result of map get"); + +done: + + if(ret_value < 0) { + num = -1; + if(HG_SUCCESS != HG_Handler_start_output(op_data->hg_handle, &num)) + 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)) + HGOTO_ERROR(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; + 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_size_t key_size, val_size; + size_t src_size, dst_size; + void *key_buf = NULL; + hbool_t opened_locally = FALSE; + htri_t exists; + 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_write(coh, iod_id, NULL /*hints*/, &iod_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); + opened_locally = TRUE; + } + + /* Check (and do) Type conversion on the Key */ + src_size = H5Tget_size(key_memtype_id); + dst_size = H5Tget_size(key_maptype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size < dst_size) { + key_size = dst_size; + } + else { + key_size = src_size; + } + + if(NULL == (key_buf = malloc(key_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + memcpy(key_buf, key.buf, src_size); + + if(H5Tconvert(key_memtype_id, key_maptype_id, 1, key_buf, NULL, H5P_DEFAULT) < 0) + HGOTO_ERROR(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, IOD_TID_UNKNOWN, key_buf, 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_ERROR(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"); + } + + if(key_buf) + free(key_buf); + + 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)) + HGOTO_ERROR(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; + 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_size_t key_size; + size_t src_size, dst_size; + void *key_buf = NULL; + iod_kv_t kv; + iod_kv_params_t kvs; + hbool_t opened_locally = 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, NULL /*hints*/, &iod_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); + opened_locally = TRUE; + } + + /* Check (and do) Type conversion on the Key */ + src_size = H5Tget_size(key_memtype_id); + dst_size = H5Tget_size(key_maptype_id); + + /* adjust buffer size for datatype conversion */ + if(src_size < dst_size) { + key_size = dst_size; + } + else { + key_size = src_size; + } + + if(NULL == (key_buf = malloc(key_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + memcpy(key_buf, key.buf, src_size); + + if(H5Tconvert(key_memtype_id, key_maptype_id, 1, key_buf, NULL, H5P_DEFAULT) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed") + + kv.key = key_buf; + kvs.kv = &kv; + + if(iod_kv_unlink_keys(iod_oh,IOD_TID_UNKNOWN, NULL, 1, &kvs, NULL) < 0) + HGOTO_ERROR(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"); + + if(key_buf) + free(key_buf); + + 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)) + HGOTO_ERROR(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_handle_t iod_oh = input->iod_oh; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start map close\n"); +#endif + + if(iod_oh.cookie != IOD_OH_UNDEFINED) { + if((ret_value = iod_obj_close(iod_oh, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + } + else { + /* MSC - need a way to kill object handle for this map */ + fprintf(stderr, "I do not have the OH of this map to close it\n"); + } +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_server.c b/src/H5VLiod_server.c index 800d382..7dcedfa 100644 --- a/src/H5VLiod_server.c +++ b/src/H5VLiod_server.c @@ -101,6 +101,23 @@ H5VLiod_start_handler(MPI_Comm comm, MPI_Info UNUSED info) 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, @@ -2245,6 +2262,447 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_server_object_get_comment() */ + +/*------------------------------------------------------------------------- + * 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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_create_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_create_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_open_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_open_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_set_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_set_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_get_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_get_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_get_count_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_get_count_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_exists_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_exists_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_id) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + 1, &input->parent_axe_id, 0, NULL, + H5VL_iod_server_map_delete_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_delete_cb, op_data, NULL)) + HGOTO_ERROR(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_ERROR(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_ERROR(H5E_SYM, H5E_NOSPACE, HG_FAIL, "can't allocate axe op_data struct"); + + if(HG_FAIL == HG_Handler_get_input(handle, input)) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, HG_FAIL, "can't get input parameters"); + + if(NULL == engine) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "AXE engine not started"); + + op_data->hg_handle = handle; + op_data->input = (void *)input; + + if(input->parent_axe_ids.count) { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, + input->parent_axe_ids.count, input->parent_axe_ids.ids, + 0, NULL, + H5VL_iod_server_map_close_cb, op_data, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, HG_FAIL, "can't insert task into async engine"); + } + else { + if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, 0, NULL, 0, NULL, + H5VL_iod_server_map_close_cb, op_data, NULL)) + HGOTO_ERROR(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() */ + herr_t H5VL_iod_server_traverse(iod_handle_t coh, iod_obj_id_t loc_id, iod_handle_t loc_handle, const char *path, hbool_t create_interm_grps, diff --git a/src/H5VLiod_server.h b/src/H5VLiod_server.h index 2110de4..0a7a643 100644 --- a/src/H5VLiod_server.h +++ b/src/H5VLiod_server.h @@ -61,6 +61,14 @@ 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); @@ -143,6 +151,38 @@ 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[], diff --git a/src/H5private.h b/src/H5private.h index a55fbcd5..2f90c45 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -2370,6 +2370,7 @@ 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 H5R_term_interface(void); diff --git a/src/Makefile.am b/src/Makefile.am index 1a9837f..f0ae8c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,11 +61,12 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5FAstat.c H5FAtest.c \ H5VL.c H5VLint.c H5VLnative.c \ H5VLiod.c H5VLiod_client.c H5VLiod_server.c H5VLiod_encdec.c \ - H5VLiod_file.c H5VLiod_group.c H5VLiod_dset.c H5VLiod_dtype.c H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c \ + H5VLiod_file.c H5VLiod_group.c H5VLiod_dset.c H5VLiod_dtype.c \ + H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c H5VLiod_map.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 H5EQ.c \ + H5FF.c H5EQ.c H5M.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 \ @@ -121,7 +122,7 @@ 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 H5VLiod.h H5FFpublic.h H5EQpublic.h\ + H5VLpublic.h H5VLnative.h H5VLiod.h H5FFpublic.h H5EQpublic.h H5Mpublic.h\ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h \ H5PLextern.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 59dce77..71d68a8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -138,11 +138,11 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5VLint.lo H5VLnative.lo H5VLiod.lo H5VLiod_client.lo \ H5VLiod_server.lo H5VLiod_encdec.lo H5VLiod_file.lo \ H5VLiod_group.lo H5VLiod_dset.lo H5VLiod_dtype.lo \ - H5VLiod_attr.lo H5VLiod_link.lo H5VLiod_obj.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 H5EQ.lo H5FL.lo \ - H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \ + H5VLiod_attr.lo H5VLiod_link.lo H5VLiod_obj.lo H5VLiod_map.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 H5EQ.lo H5M.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 H5Goh.lo \ @@ -570,11 +570,12 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5FAstat.c H5FAtest.c \ H5VL.c H5VLint.c H5VLnative.c \ H5VLiod.c H5VLiod_client.c H5VLiod_server.c H5VLiod_encdec.c \ - H5VLiod_file.c H5VLiod_group.c H5VLiod_dset.c H5VLiod_dtype.c H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c \ + H5VLiod_file.c H5VLiod_group.c H5VLiod_dset.c H5VLiod_dtype.c \ + H5VLiod_attr.c H5VLiod_link.c H5VLiod_obj.c H5VLiod_map.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 H5EQ.c \ + H5FF.c H5EQ.c H5M.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 \ @@ -630,7 +631,7 @@ 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 H5VLiod.h H5FFpublic.h H5EQpublic.h\ + H5VLpublic.h H5VLnative.h H5VLiod.h H5FFpublic.h H5EQpublic.h H5Mpublic.h\ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h \ H5PLextern.h \ @@ -917,6 +918,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@ @@ -1033,6 +1035,7 @@ distclean-compile: @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)/H5VLnative.Plo@am__quote@ |