diff options
author | Vishwanath Venkatesan <vish@hdfgroup.org> | 2013-07-17 22:55:39 (GMT) |
---|---|---|
committer | Vishwanath Venkatesan <vish@hdfgroup.org> | 2013-07-17 22:55:39 (GMT) |
commit | 73a4a38334fe4616904a2afe3de202e68b4818f0 (patch) | |
tree | a9dd252151ce6318c9969e71402673929efb3144 | |
parent | 0299f1749b7c74e94517f7f653e4992b8bc499d5 (diff) | |
parent | 9af20ef8d82f5d87f9aaba9543f476752f5e8b9a (diff) | |
download | hdf5-73a4a38334fe4616904a2afe3de202e68b4818f0.zip hdf5-73a4a38334fe4616904a2afe3de202e68b4818f0.tar.gz hdf5-73a4a38334fe4616904a2afe3de202e68b4818f0.tar.bz2 |
[svn-r23915] Merge changes with hdf5_ff and minor fixes to the compactor_write.
Tested for larger number of processes too.
32 files changed, 5225 insertions, 869 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2940c74..2d64d14 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -54,15 +54,21 @@ IF (H5_HAVE_PARALLEL) ENDIF (H5_HAVE_PARALLEL) IF (H5_HAVE_EFF) - ADD_EXECUTABLE (test_server ${HDF5_EXAMPLES_SOURCE_DIR}/test_server.c) - TARGET_LINK_LIBRARIES (test_server ${HDF5_LIB_TARGET}) - SET_TARGET_PROPERTIES (test_server PROPERTIES FOLDER examples) - ADD_EXECUTABLE (test_client ${HDF5_EXAMPLES_SOURCE_DIR}/test_client.c) - TARGET_LINK_LIBRARIES (test_client ${HDF5_LIB_TARGET}) - SET_TARGET_PROPERTIES (test_client PROPERTIES FOLDER examples) - ADD_EXECUTABLE (test_client_acg ${HDF5_EXAMPLES_SOURCE_DIR}/test_client_acg.c) - TARGET_LINK_LIBRARIES (test_client_acg ${HDF5_LIB_TARGET}) - SET_TARGET_PROPERTIES (test_client_acg PROPERTIES FOLDER examples) + ADD_EXECUTABLE (h5ff_server ${HDF5_EXAMPLES_SOURCE_DIR}/h5ff_server.c) + TARGET_LINK_LIBRARIES (h5ff_server ${HDF5_LIB_TARGET}) + SET_TARGET_PROPERTIES (h5ff_server PROPERTIES FOLDER examples) + ADD_EXECUTABLE (h5ff_client ${HDF5_EXAMPLES_SOURCE_DIR}/h5ff_client.c) + TARGET_LINK_LIBRARIES (h5ff_client ${HDF5_LIB_TARGET}) + SET_TARGET_PROPERTIES (h5ff_client PROPERTIES FOLDER examples) + ADD_EXECUTABLE (h5ff_client_do ${HDF5_EXAMPLES_SOURCE_DIR}/h5ff_client_do.c) + TARGET_LINK_LIBRARIES (h5ff_client_do ${HDF5_LIB_TARGET}) + SET_TARGET_PROPERTIES (h5ff_client_do PROPERTIES FOLDER examples) + ADD_EXECUTABLE (h5ff_client_map ${HDF5_EXAMPLES_SOURCE_DIR}/h5ff_client_map.c) + TARGET_LINK_LIBRARIES (h5ff_client_map ${HDF5_LIB_TARGET}) + SET_TARGET_PROPERTIES (h5ff_client_map PROPERTIES FOLDER examples) + ADD_EXECUTABLE (h5ff_client_old_api ${HDF5_EXAMPLES_SOURCE_DIR}/h5ff_client_old_api.c) + TARGET_LINK_LIBRARIES (h5ff_client_old_api ${HDF5_LIB_TARGET}) + SET_TARGET_PROPERTIES (h5ff_client_old_api PROPERTIES FOLDER examples) ENDIF (H5_HAVE_EFF) IF (BUILD_TESTING) diff --git a/examples/Makefile.am b/examples/Makefile.am index 096c9fc..5b45e0a 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 = h5ff_server h5ff_client h5ff_client_map h5ff_client_old_api h5ff_client_do endif # Example programs. diff --git a/examples/Makefile.in b/examples/Makefile.in index 47dc829..68a92bb 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 = h5ff_server h5ff_client h5ff_client_map h5ff_client_old_api h5ff_client_do # Example programs. # Don't tell automake about them, because if it knew they were programs, diff --git a/examples/test_client.c b/examples/h5ff_client.c index 74abac2..8af2686 100644 --- a/examples/test_client.c +++ b/examples/h5ff_client.c @@ -533,7 +533,7 @@ int main(int argc, char **argv) { /* get operations on the group */
{
- ssize_t ret_size;
+ ssize_t ret_size = 0;
char *comment = NULL;
ret = H5Oget_comment_ff(gid1, NULL, 0, &ret_size, 0, event_q);
@@ -545,7 +545,7 @@ int main(int argc, char **argv) { assert (status1);
fprintf(stderr, "size of comment is %d\n", ret_size);
- comment = malloc((size_t)ret_size);
+ comment = malloc((size_t)ret_size + 1);
ret = H5Oget_comment_ff(gid1, comment, (size_t)ret_size + 1, &ret_size, 0, event_q);
assert(ret == 0);
@@ -612,6 +612,7 @@ int main(int argc, char **argv) { H5Sclose(mem_space);
}
+ H5Sclose(dataspaceId);
assert(H5Dclose(did1) == 0);
/* open attribute on dataset D1. This is asynchronous */
@@ -658,7 +659,6 @@ int main(int argc, char **argv) { H5EQclose(event_q);
H5Pclose(fapl_id);
- H5Sclose(dataspaceId);
/*
assert(H5AOwait(&req1, &status1) == 0);
diff --git a/examples/test_client_acg.c b/examples/h5ff_client_do.c index c22517f..c4b2340 100644 --- a/examples/test_client_acg.c +++ b/examples/h5ff_client_do.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/h5ff_client_map.c b/examples/h5ff_client_map.c new file mode 100644 index 0000000..59228f1 --- /dev/null +++ b/examples/h5ff_client_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/examples/test_client_old_api.c b/examples/h5ff_client_old_api.c index b943539..7875b97 100644 --- a/examples/test_client_old_api.c +++ b/examples/h5ff_client_old_api.c @@ -1,9 +1,3 @@ -/*
- * test_client.c: Client side of Milestone 3.3 Asynchronous I/O and initial
- * IOD VOL plugin demonstration. This is, in effect, the application program that
- * would run on one or more compute nodes and make calls to the HDF5 API.
- */
-
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -237,15 +231,15 @@ int main(int argc, char **argv) { gid1 = H5Gopen2(file_id, "G1", H5P_DEFAULT);
assert(gid1);
{
- ssize_t ret_size;
+ ssize_t ret_size = 0;
char *comment = NULL;
ret_size = H5Oget_comment(gid1, NULL, 0);
fprintf(stderr, "size of comment is %d\n", ret_size);
- comment = malloc((size_t)ret_size);
+ comment = malloc((size_t)ret_size + 1);
- ret_size = H5Oget_comment(gid1, comment, (size_t)ret_size + 1);
+ H5Oget_comment(gid1, comment, (size_t)ret_size + 1);
fprintf(stderr, "size of comment is %d Comment is %s\n", ret_size, comment);
free(comment);
}
@@ -284,4 +278,3 @@ int main(int argc, char **argv) { MPI_Finalize();
return 0;
}
-
diff --git a/examples/test_server.c b/examples/h5ff_server.c index 5d71e35..dc5f4a4 100644 --- a/examples/test_server.c +++ b/examples/h5ff_server.c @@ -24,7 +24,7 @@ int main(int argc, char **argv) { MPI_Comm_size(MPI_COMM_WORLD, &my_size);
printf("Number of server processes = %d, my rank is %d\n", my_size, my_rank);
- H5open();
+ //H5open();
/* This call initiliazes the FS for the server processes (create metadata and
bulk data handles). It also registers with the Function shipper the
HDF5 VOL server routines that will be executed when the clients ship the VOL
@@ -40,7 +40,7 @@ int main(int argc, char **argv) { Finally, when all clients send a terminate call, the function shipper interface
is finalized the operation returns. */
H5VLiod_start_handler(MPI_COMM_WORLD, MPI_INFO_NULL);
- H5close();
+ //H5close();
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..52cfca8 --- /dev/null +++ b/src/H5M.c @@ -0,0 +1,908 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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) + H5TRACE2("e", "ii", map_id, eq_id); + + /* Check args */ + if(NULL == H5I_object_verify(map_id, H5I_MAP)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(map_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_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/H5Spublic.h b/src/H5Spublic.h index 96953d8..f2c9093 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -114,6 +114,7 @@ H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t count[], const hsize_t _block[]); + #define NEW_HYPERSLAB_API H5_DLL htri_t H5Sselect_is_regular(hid_t space_id); @@ -123,6 +124,7 @@ H5_DLL herr_t H5Sget_reg_hyperslab_params(hid_t space_id, hsize_t count[], hsize_t block[]); + /* Note that these haven't been working for a while and were never * publicly released - QAK */ #ifdef NEW_HYPERSLAB_API diff --git a/src/H5VLiod.c b/src/H5VLiod.c index 6855ca1..e126dd0 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); @@ -4778,6 +4800,7 @@ H5VL_iod_link_create(H5VL_link_create_type_t create_type, void *_obj, H5VL_loc_p if(NULL == target_obj && obj) { target_obj = obj; } + /* Retrieve the parent info by traversing the path where the link should be created. */ if(H5VL_iod_get_parent_info(target_obj, target_params, ".", @@ -6322,4 +6345,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_attr.c b/src/H5VLiod_attr.c index dda7b6a..dd8c786 100644 --- a/src/H5VLiod_attr.c +++ b/src/H5VLiod_attr.c @@ -47,19 +47,17 @@ H5VL_iod_server_attr_create_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; attr_create_in_t *input = (attr_create_in_t *)op_data->input; attr_create_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ iod_obj_id_t attr_id = input->attr_id; /* The ID of the attribute that needs to be created */ - iod_handle_t attr_oh, attr_kv_oh, cur_oh, mdkv_oh; + iod_handle_t attr_oh, attr_kv_oh, cur_oh, mdkv_oh; /* object handles */ iod_obj_id_t cur_id, mdkv_id; - const char *loc_name = input->path; - const char *attr_name = input->attr_name; - char *last_comp = NULL; - iod_array_struct_t array; - iod_size_t *max_dims; - iod_kv_t kv; - size_t buf_size; + const char *loc_name = input->path; /* path to start hierarchy traversal */ + const char *attr_name = input->attr_name; /* attribute's name */ + char *last_comp = NULL; /* the last component's name where attribute is created */ + iod_array_struct_t array; /* IOD array structure for attribute's creation */ + iod_size_t *max_dims; /* MAX dims for IOD */ scratch_pad_t sp; iod_ret_t ret; hbool_t collective = FALSE; /* MSC - change when we allow for collective */ @@ -121,46 +119,26 @@ H5VL_iod_server_attr_create_cb(AXE_engine_t UNUSED axe_engine, if (iod_obj_set_scratch(attr_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 */ + /* Open Metadata KV object for write */ 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 */ + /* insert object type metadata */ + if(H5VL_iod_insert_object_type(mdkv_oh, IOD_TID_UNKNOWN, H5I_ATTR, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); -#if 0 - /* insert attribute metadata into scratch pad */ - kv.key = HDstrdup("attribute_dtype"); - /* determine the buffer size needed to store the encoded type of the attribute */ - if(H5Tencode(input->type_id, NULL, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode attribute type"); - if(NULL == (kv.value = malloc (buf_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer"); - /* encode datatype of the attribute */ - if(H5Tencode(input->type_id, kv.value, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode attribute type"); - kv.value_len = (iod_size_t)buf_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); - - kv.key = HDstrdup("attribute_dspace"); - /* determine the buffer size needed to store the encoded space of the attribute */ - if(H5Sencode(input->space_id, NULL, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode attribute space"); - if(NULL == (kv.value = malloc (buf_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate space buffer"); - /* encode dataspace of the attribute */ - if(H5Sencode(input->space_id, kv.value, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode attribute space"); - kv.value_len = (iod_size_t)buf_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); -#endif + /* MSC - need to check size of datatype if it fits in + entry otherwise create a BLOB*/ + /* insert datatype metadata */ + if(H5VL_iod_insert_datatype(mdkv_oh, IOD_TID_UNKNOWN, input->type_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert dataspace metadata */ + if(H5VL_iod_insert_dataspace(mdkv_oh, IOD_TID_UNKNOWN, input->space_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); /* close the Metadata KV object */ if(iod_obj_close(mdkv_oh, NULL, NULL)) @@ -170,31 +148,18 @@ H5VL_iod_server_attr_create_cb(AXE_engine_t UNUSED axe_engine, if(iod_obj_get_scratch(cur_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object"); - /* if attribute KV does not exist, create it */ - if(IOD_ID_UNDEFINED == sp.attr_id) { - /* create the attribute KV object for the parent */ - if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, - NULL, NULL, &sp.attr_id, NULL)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Attr KV"); - - /* set scratch pad in attribute */ - if (iod_obj_set_scratch(cur_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad"); - } - /* open the attribute KV in scratch pad */ if (iod_obj_open_write(coh, sp.attr_id, NULL /*hints*/, &attr_kv_oh, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't open scratch pad"); /* insert new attribute in scratch pad of current object */ - kv.key = HDstrdup(attr_name); - kv.value = &attr_id; - kv.value_len = 0; - if (iod_kv_set(attr_kv_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); - - iod_obj_close(attr_kv_oh, NULL, NULL); + if(H5VL_iod_insert_new_link(attr_kv_oh, IOD_TID_UNKNOWN, attr_name, attr_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* close the Attribute KV object */ + if(iod_obj_close(attr_kv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); } /* close parent group if it is not the location we started the @@ -257,15 +222,15 @@ H5VL_iod_server_attr_open_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; attr_open_in_t *input = (attr_open_in_t *)op_data->input; attr_open_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start traversal */ + iod_obj_id_t loc_id = input->loc_id; /* location ID */ iod_handle_t attr_kv_oh, cur_oh, mdkv_oh; iod_obj_id_t cur_id, mdkv_id; iod_obj_id_t attr_id; - const char *loc_name = input->path; - const char *attr_name = input->attr_name; - char *last_comp = NULL; + const char *loc_name = input->path; /* current path to start traversal */ + const char *attr_name = input->attr_name; /* attribute's name to open */ + char *last_comp = NULL; /* name of last object in path */ scratch_pad_t sp; herr_t ret_value = SUCCEED; @@ -322,7 +287,15 @@ H5VL_iod_server_attr_open_cb(AXE_engine_t UNUSED axe_engine, 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 all metadata from scratch pad */ +#if 0 + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATATYPE, "datatype", + NULL, NULL, NULL, &output.type_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype"); + + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATASPACE, "dataspace", + NULL, NULL, NULL, &output.space_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace"); +#endif /* close the metadata scratch pad */ if(iod_obj_close(mdkv_oh, NULL, NULL)) @@ -400,19 +373,24 @@ H5VL_iod_server_attr_read_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_io_in_t *input = (attr_io_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t iod_oh = input->iod_oh; - iod_obj_id_t iod_id = input->iod_id; - hg_bulk_t bulk_handle = input->bulk_handle; - hid_t type_id = input->type_id; - hg_bulk_block_t bulk_block_handle; - hg_bulk_request_t bulk_request; - iod_mem_desc_t mem_desc; - iod_array_iodesc_t file_desc; - size_t size; - void *buf; - na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); - hbool_t opened_locally = FALSE; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t iod_oh = input->iod_oh; /* attribute's object handle */ + iod_obj_id_t iod_id = input->iod_id; /* attribute's ID */ + hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */ + hid_t type_id = input->type_id; /* datatype ID of data */ + hg_bulk_block_t bulk_block_handle; /* HG block handle */ + hg_bulk_request_t bulk_request; /* HG request */ + iod_mem_desc_t mem_desc; /* memory descriptor used for reading array */ + iod_array_iodesc_t file_desc; /* file descriptor used to read array */ + iod_hyperslab_t hslabs; /* IOD hyperslab generated from HDF5 filespace */ + size_t size; /* size of outgoing bulk data */ + void *buf; /* buffer to hold outgoing data */ + hid_t space_id; /* dataspace ID of attribute */ + iod_handle_t mdkv_oh; /* metadata KV handle of attribute */ + scratch_pad_t sp; + hssize_t num_descriptors = 0; /* number of IOD file descriptors needed to describe filespace selection */ + na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */ + hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the attribute here or if it was already open */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -429,14 +407,46 @@ H5VL_iod_server_attr_read_cb(AXE_engine_t UNUSED axe_engine, if(NULL == (buf = malloc(size))) HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate read buffer"); + /* MSC - NEED IOD */ #if 0 + /* get scratch pad of the attribute */ + if(iod_obj_get_scratch(iod_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object"); + + /* open the metadata scratch pad of the attribute */ + 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"); + + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATASPACE, "dataspace", + NULL, NULL, NULL, &space_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace"); + + /* close the metadata scratch pad */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + /* create memory descriptor for reading */ mem_desc.nfrag = 1; mem_desc.frag->addr = buf; mem_desc.frag->len = (iod_size_t)size; - /* retrieve the dataspace of the attribute and create file descriptor for reading */ - /* MSC TODO - populate file descriptor hyperslab */ + num_descriptors = 1; + + /* get the rank of the dataspace */ + if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion"); + + hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + + /* generate the descriptor */ + if(H5VL_iod_get_file_desc(space_id, &num_descriptors, hslabs) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection"); + + /* set the file descriptor */ + file_desc = hslabs; #endif /* read from array object */ @@ -463,7 +473,7 @@ H5VL_iod_server_attr_read_cb(AXE_engine_t UNUSED axe_engine, if(HG_SUCCESS != HG_Bulk_write_all(dest, bulk_handle, bulk_block_handle, &bulk_request)) HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object"); /* wait for it to complete */ - if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_BULK_MAX_IDLE_TIME, HG_BULK_STATUS_IGNORE)) + if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE)) HGOTO_ERROR(H5E_SYM, H5E_READERROR, FAIL, "can't read from array object"); done: @@ -511,20 +521,24 @@ H5VL_iod_server_attr_write_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_io_in_t *input = (attr_io_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t iod_oh = input->iod_oh; - iod_obj_id_t iod_id = input->iod_id; - hg_bulk_t bulk_handle = input->bulk_handle; - hid_t type_id = input->type_id; - hg_bulk_block_t bulk_block_handle; - hg_bulk_request_t bulk_request; - iod_mem_desc_t mem_desc; - iod_array_iodesc_t file_desc; - size_t size; - void *buf; - ssize_t ret; - na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); - hbool_t opened_locally = FALSE; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t iod_oh = input->iod_oh; /* attribute's object handle */ + iod_obj_id_t iod_id = input->iod_id; /* attribute's ID */ + hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */ + hid_t type_id = input->type_id; /* datatype ID of data */ + hg_bulk_block_t bulk_block_handle; /* HG block handle */ + hg_bulk_request_t bulk_request; /* HG request */ + iod_mem_desc_t mem_desc; /* memory descriptor used for writing array */ + iod_array_iodesc_t file_desc; /* file descriptor used to write array */ + iod_hyperslab_t hslabs; /* IOD hyperslab generated from HDF5 filespace */ + size_t size; /* size of outgoing bulk data */ + void *buf; /* buffer to hold outgoing data */ + hid_t space_id; /* dataspace ID of attribute */ + scratch_pad_t sp; + iod_handle_t mdkv_oh; /* metadata KV handle of attribute */ + hssize_t num_descriptors = 0; /* number of IOD file descriptors needed to describe filespace selection*/ + na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); /* source address to pull data from */ + hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the attribute here or if it was already opened */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -546,7 +560,7 @@ H5VL_iod_server_attr_write_cb(AXE_engine_t UNUSED axe_engine, if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, bulk_block_handle, &bulk_request)) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper"); /* wait for it to complete */ - if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_BULK_MAX_IDLE_TIME, HG_BULK_STATUS_IGNORE)) + if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE)) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper"); /* free the bds block handle */ @@ -565,13 +579,45 @@ H5VL_iod_server_attr_write_cb(AXE_engine_t UNUSED axe_engine, } #endif + /* MSC - NEED IOD */ #if 0 + /* get scratch pad of the attribute */ + if(iod_obj_get_scratch(iod_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't get scratch pad for object"); + + /* open the metadata scratch pad of the attribute */ + 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"); + + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATASPACE, "dataspace", + NULL, NULL, NULL, &space_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace"); + + /* close the metadata scratch pad */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + mem_desc.nfrag = 1; mem_desc.frag->addr = buf; mem_desc.frag->len = (iod_size_t)size; - /* retrieve the dataspace of the attribute and create file descriptor for reading */ - /* MSC TODO - populate file descriptor hyperslab */ + num_descriptors = 1; + + /* get the rank of the dataspace */ + if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion"); + + hslabs.start = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.stride = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.block = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + hslabs.count = (iod_size_t *)malloc(sizeof(iod_size_t) * ndims); + + /* generate the descriptor */ + if(H5VL_iod_get_file_desc(space_id, &num_descriptors, hslabs) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to generate IOD file descriptor from dataspace selection"); + + /* set the file descriptor */ + file_desc = hslabs; #endif /* write from array object */ @@ -594,7 +640,7 @@ done: op_data = (op_data_t *)H5MM_xfree(op_data); free(buf); - /* close the dataset if we opened it in this routine */ + /* close the attribute 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"); @@ -624,14 +670,15 @@ H5VL_iod_server_attr_exists_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_op_in_t *input = (attr_op_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; - iod_handle_t cur_oh, attr_kv_oh; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_handle_t cur_oh; /* current object handle accessed */ + iod_handle_t attr_kv_oh; /* KV handle holding attributes for object */ iod_obj_id_t cur_id, attr_id; - const char *loc_name = input->path; - const char *attr_name = input->attr_name; - char *last_comp = NULL; + const char *loc_name = input->path; /* path to start hierarchy traversal */ + const char *attr_name = input->attr_name; /* attribute's name */ + char *last_comp = NULL; /* the last component's name where attribute is created */ scratch_pad_t sp; htri_t ret = -1; herr_t ret_value = SUCCEED; @@ -726,17 +773,18 @@ H5VL_iod_server_attr_rename_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_rename_in_t *input = (attr_rename_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; - iod_handle_t cur_oh, attr_kv_oh; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_handle_t cur_oh; /* current object handle accessed */ + iod_handle_t attr_kv_oh; /* KV handle holding attributes for object */ iod_obj_id_t cur_id, attr_id; - const char *loc_name = input->path; + const char *loc_name = input->path; /* path to start hierarchy traversal */ const char *old_name = input->old_attr_name; const char *new_name = input->new_attr_name; - char *last_comp = NULL; - iod_kv_params_t kvs; - iod_kv_t kv; + char *last_comp = NULL; /* the last component's name where attribute is created */ + iod_kv_params_t kvs; /* KV lists for objects - used to unlink attribute object */ + iod_kv_t kv; /* KV entry */ scratch_pad_t sp; herr_t ret_value = SUCCEED; @@ -784,18 +832,17 @@ H5VL_iod_server_attr_rename_cb(AXE_engine_t UNUSED axe_engine, kv.value = &attr_id; kv.value_len = sizeof(iod_obj_id_t); kvs.kv = &kv; - if(iod_kv_unlink_keys(attr_kv_oh,IOD_TID_UNKNOWN, NULL, 1, &kvs, NULL) < 0) + if(iod_kv_unlink_keys(attr_kv_oh, IOD_TID_UNKNOWN, NULL, 1, &kvs, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "Unable to unlink KV pair"); /* insert attribute with new name */ - kv.key = strdup(new_name); - kv.value = &attr_id; - kv.value_len = sizeof(iod_obj_id_t); - if (iod_kv_set(attr_kv_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); + if(H5VL_iod_insert_new_link(attr_kv_oh, IOD_TID_UNKNOWN, new_name, attr_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); - iod_obj_close(attr_kv_oh, NULL, NULL); + /* close the Attribute KV object */ + if(iod_obj_close(attr_kv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); #if H5_DO_NATIVE ret_value = H5Arename(loc_handle.cookie, old_name, new_name); @@ -838,14 +885,15 @@ H5VL_iod_server_attr_remove_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_op_in_t *input = (attr_op_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; - iod_handle_t cur_oh, attr_kv_oh; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_handle_t cur_oh; /* current object handle accessed */ + iod_handle_t attr_kv_oh; /* KV handle holding attributes for object */ iod_obj_id_t cur_id, attr_id; - const char *loc_name = input->path; - const char *attr_name = input->attr_name; - char *last_comp = NULL; + const char *loc_name = input->path; /* path to start hierarchy traversal */ + const char *attr_name = input->attr_name; /* attribute's name */ + char *last_comp = NULL; /* the last component's name where attribute is created */ iod_kv_params_t kvs; iod_kv_t kv; scratch_pad_t sp; @@ -941,8 +989,8 @@ H5VL_iod_server_attr_close_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; attr_close_in_t *input = (attr_close_in_t *)op_data->input; - iod_handle_t iod_oh = input->iod_oh; - iod_obj_id_t iod_id = input->iod_id; + iod_handle_t iod_oh = input->iod_oh; /* iod handle to close */ + iod_obj_id_t iod_id = input->iod_id; /* iod id of object to close */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c index 66825dc..003d743 100644 --- a/src/H5VLiod_client.c +++ b/src/H5VLiod_client.c @@ -41,6 +41,17 @@ H5FL_EXTERN(H5VL_iod_group_t); H5FL_EXTERN(H5VL_iod_dset_t); H5FL_EXTERN(H5VL_iod_dtype_t); + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_add + * + * Purpose: Adds a request pointer to the Doubly linked list on the + * file. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request) { @@ -63,6 +74,17 @@ H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request) FUNC_LEAVE_NOAPI(SUCCEED) } + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_delete + * + * Purpose: Removes a request pointer from the Doubly linked list on the + * file. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request) { @@ -103,6 +125,22 @@ H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request) FUNC_LEAVE_NOAPI(SUCCEED) } + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_wait + * + * Purpose: + * Waits for a particular request to complete. This will test + * the request completion using Mercury's test routine. If the + * request is still pending we test for completion of other requests in + * the file's linked list to try and keep making progress. Once the + * original requests completes, we remove it from the linked list + * and return. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) { @@ -180,6 +218,16 @@ H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL_iod_wait */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_wait_all + * + * Purpose: Wait and complete all the requests in the linked list. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_wait_all(H5VL_iod_file_t *file) { @@ -218,6 +266,17 @@ H5VL_iod_request_wait_all(H5VL_iod_file_t *file) FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_request_wait_all */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_wait_some + * + * Purpose: Wait for some requests on the linked list, particularly + * the ones that are tracked with a particular object. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object) { @@ -259,6 +318,18 @@ H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object) FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_request_wait_some */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_complete + * + * Purpose: Completion calls for every type of request. This checks + * the return status from the server, and frees memory + * allocated by this request. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) { @@ -307,6 +378,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 +500,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 +738,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; @@ -668,6 +835,17 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_request_complete */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_request_cancel + * + * Purpose: Cancels a particular request by freeing memory + * associated with it. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_request_cancel(H5VL_iod_file_t *file, H5VL_iod_request_t *req) { @@ -747,6 +925,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 +1037,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 +1089,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: @@ -922,8 +1137,21 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_request_cancel */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_get_axe_parents + * + * Purpose: returns the number of axe_id tasks that are associated + * with a particular object. If the parent array is not NULL, + * the axe_ids are returned in parents too. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t -H5VL_iod_get_axe_parents(H5VL_iod_object_t *obj, size_t *count, uint64_t *parents) +H5VL_iod_get_axe_parents(H5VL_iod_object_t *obj, /*IN/OUT*/ size_t *count, + /*OUT*/ uint64_t *parents) { H5VL_iod_file_t *file = obj->file; H5VL_iod_request_t *cur_req = file->request_list_head; @@ -950,10 +1178,28 @@ H5VL_iod_get_axe_parents(H5VL_iod_object_t *obj, size_t *count, uint64_t *parent FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL_iod_get_axe_parents */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_get_parent_info + * + * Purpose: This routine traverses the path in name, or in loc_params + * if the path is specified there, to determine the components + * of the path that are present locally in the ID space. + * Once a component in the path is not found, the routine + * breaks at that point and stores the remaining path in new_name. + * This is where the traversal can begin at the server. + * The IOD ID, OH, and axe_id belonging to the last object + * present are returned too. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_get_parent_info(H5VL_iod_object_t *obj, H5VL_loc_params_t loc_params, - const char *name, iod_obj_id_t *iod_id, iod_handle_t *iod_oh, - uint64_t *axe_id, char **new_name, H5VL_iod_object_t **last_obj) + const char *name, /*OUT*/iod_obj_id_t *iod_id, + /*OUT*/iod_handle_t *iod_oh, /*OUT*/uint64_t *axe_id, + /*OUT*/char **new_name, /*OUT*/H5VL_iod_object_t **last_obj) { iod_obj_id_t cur_id; iod_handle_t cur_oh; @@ -1091,6 +1337,18 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_get_parent_info */ + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_get_axe_parents + * + * Purpose: routine to generate an IOD ID based on the object type, + * rank and total ranks, and current index or + * number of pre-existing IDs. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ herr_t H5VL_iod_gen_obj_id(int myrank, int nranks, uint64_t cur_index, iod_obj_type_t type, uint64_t *id) 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 e58ab39..1a75e2c 100644 --- a/src/H5VLiod_common.h +++ b/src/H5VLiod_common.h @@ -49,7 +49,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 { @@ -59,6 +59,17 @@ typedef struct name_t { } 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); @@ -68,6 +79,8 @@ 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_value_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))) @@ -125,6 +138,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 294895f..f33f136 100644 --- a/src/H5VLiod_dset.c +++ b/src/H5VLiod_dset.c @@ -20,6 +20,7 @@ #ifdef H5_HAVE_EFF + /* * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> * June, 2013 @@ -27,440 +28,411 @@ * Purpose: The IOD plugin server side dataset routines. */ - - /*------------------------------------------------------------------------- - * Function: H5VL_iod_server_dset_create_cb - * - * Purpose: Creates a dset as a iod object. - * - * Return: Success: SUCCEED - * Failure: Negative - * - * Programmer: Mohamad Chaarawi - * February, 2013 - * - *------------------------------------------------------------------------- - */ - void - H5VL_iod_server_dset_create_cb(AXE_engine_t UNUSED axe_engine, - size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], - size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], - void *_op_data) - { - op_data_t *op_data = (op_data_t *)_op_data; - dset_create_in_t *input = (dset_create_in_t *)op_data->input; - dset_create_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ - iod_obj_id_t dset_id = input->dset_id; /* The ID of the dataset that needs to be created */ - iod_handle_t dset_oh, cur_oh, mdkv_oh; - iod_obj_id_t cur_id, mdkv_id; - const char *name = input->name; - char *last_comp; /* the name of the dataset obtained from the last component in the path */ - iod_kv_t kv; - iod_array_struct_t array; - iod_size_t *max_dims; - size_t buf_size; - 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 + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_server_dset_create_cb + * + * Purpose: Creates a dset as a iod object. + * + * Return: Success: SUCCEED + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * February, 2013 + * + *------------------------------------------------------------------------- + */ +void +H5VL_iod_server_dset_create_cb(AXE_engine_t UNUSED axe_engine, + size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], + size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], + void *_op_data) +{ + op_data_t *op_data = (op_data_t *)_op_data; + dset_create_in_t *input = (dset_create_in_t *)op_data->input; + dset_create_out_t output; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_obj_id_t dset_id = input->dset_id; /* The ID of the dataset that needs to be created */ + iod_handle_t dset_oh, cur_oh, mdkv_oh; + iod_obj_id_t cur_id, mdkv_id, attr_id; + const char *name = input->name; /* name of dset including path to create */ + char *last_comp; /* the name of the dataset obtained from the last component in the path */ + hid_t dcpl_id; + iod_array_struct_t array; /* IOD array struct describing the dataset's dimensions */ + iod_size_t *max_dims; + scratch_pad_t sp; + iod_ret_t ret; + hbool_t collective = FALSE; /* MSC - change when we allow for collective */ + herr_t ret_value = SUCCEED; - /* the traversal will retrieve the location where the dataset needs - to be created. The traversal will fail if an intermediate group - does not exist. */ - if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, FALSE, - &last_comp, &cur_id, &cur_oh) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path"); - - /* Set the IOD array creation parameters */ - array.cell_size = H5Tget_size(input->type_id); - array.num_dims = H5Sget_simple_extent_ndims(input->space_id); - if(NULL == (array.current_dims = (iod_size_t *)malloc (sizeof(iod_size_t) * array.num_dims))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dimention size array"); - if(NULL == (max_dims = (iod_size_t *)malloc (sizeof(iod_size_t) * array.num_dims))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dimention size array"); - if(H5Sget_simple_extent_dims(input->space_id, array.current_dims, max_dims) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimentions' sizes"); - array.firstdim_max = max_dims[0]; - array.chunk_dims = NULL; - array.dims_seq = NULL; - - /* MSC - NEED TO FIX THAT */ - #if 0 - if(layout.type == H5D_CHUNKED) { - if(NULL == (array.chunk_dims = malloc (sizeof(iod_size_t) * layout.u.chunk.ndims))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate chunk dimention size array"); - array.chunk_dims; - } - #endif + FUNC_ENTER_NOAPI_NOINIT - #if H5VL_IOD_DEBUG - fprintf(stderr, "now creating the dataset %s cellsize %d num dimenstions %d\n", - last_comp, array.cell_size, array.num_dims); - #endif + /* the traversal will retrieve the location where the dataset needs + to be created. The traversal will fail if an intermediate group + does not exist. */ + if(H5VL_iod_server_traverse(coh, loc_id, loc_handle, name, FALSE, + &last_comp, &cur_id, &cur_oh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't traverse path"); + + /* Set the IOD array creation parameters */ + array.cell_size = H5Tget_size(input->type_id); + array.num_dims = H5Sget_simple_extent_ndims(input->space_id); + if(NULL == (array.current_dims = (iod_size_t *)malloc (sizeof(iod_size_t) * array.num_dims))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dimention size array"); + if(NULL == (max_dims = (iod_size_t *)malloc (sizeof(iod_size_t) * array.num_dims))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dimention size array"); + if(H5Sget_simple_extent_dims(input->space_id, array.current_dims, max_dims) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get dimentions' sizes"); + array.firstdim_max = max_dims[0]; + array.chunk_dims = NULL; + array.dims_seq = NULL; + + /* MSC - NEED TO FIX THAT */ +#if 0 + if(layout.type == H5D_CHUNKED) { + if(NULL == (array.chunk_dims = malloc (sizeof(iod_size_t) * layout.u.chunk.ndims))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate chunk dimention size array"); + array.chunk_dims; + } +#endif - /* create the dataset */ - ret = iod_obj_create(coh, IOD_TID_UNKNOWN, NULL/*hints*/, IOD_OBJ_ARRAY, NULL, &array, - &dset_id, NULL /*event*/); - if(collective && (0 == ret || EEXISTS == ret)) { - /* Dataset has been created by another process, open it */ - if (iod_obj_open_write(coh, dset_id, NULL, &dset_oh, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Dataset"); - } - else if(!collective && 0 != ret) { - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Dataset"); - } +#if H5VL_IOD_DEBUG + fprintf(stderr, "now creating the dataset %s cellsize %d num dimenstions %d\n", + last_comp, array.cell_size, array.num_dims); +#endif - /* for the process that succeeded in creating the dataset, update - the parent KV, create scratch pad */ - if(0 == ret) { - /* create the metadata KV object for the dataset */ - 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 dataset */ - if (iod_obj_set_scratch(dset_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 0 - /* insert layout metadata into scratch pad */ - kv.key = HDstrdup("dataset_dcpl"); - /* determine the buffer size needed to store the encoded dcpl of the dataset */ - if(H5Pencode(input->dcpl_id, NULL, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset dcpl"); - if(NULL == (kv.value = malloc (buf_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dcpl buffer"); - /* encode dcpl of the dataset */ - if(H5Pencode(input->dcpl_id, kv.value, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset dcpl"); - kv.value_len = (iod_size_t)buf_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); - - /* insert datatyoe metadata into scratch pad */ - kv.key = HDstrdup("dataset_dtype"); - /* determine the buffer size needed to store the encoded type of the dataset */ - if(H5Tencode(input->type_id, NULL, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset type"); - if(NULL == (kv.value = malloc (buf_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer"); - /* encode datatype of the dataset */ - if(H5Tencode(input->type_id, kv.value, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset type"); - kv.value_len = (iod_size_t)buf_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); - - kv.key = HDstrdup("dataset_dspace"); - /* determine the buffer size needed to store the encoded space of the dataset */ - if(H5Sencode(input->space_id, NULL, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset space"); - if(NULL == (kv.value = malloc (buf_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate space buffer"); - /* encode dataspace of the dataset */ - if(H5Sencode(input->space_id, kv.value, &buf_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset space"); - kv.value_len = (iod_size_t)buf_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); - #endif - /* close the Metadata KV object */ - if(iod_obj_close(mdkv_oh, NULL, NULL)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - - kv.key = HDstrdup(last_comp); - kv.value = &dset_id; - kv.value_len = sizeof(iod_obj_id_t); - /* insert new dataset in kv store of current group */ - 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); - } + /* create the dataset */ + ret = iod_obj_create(coh, IOD_TID_UNKNOWN, NULL/*hints*/, IOD_OBJ_ARRAY, NULL, &array, + &dset_id, NULL /*event*/); + if(collective && (0 == ret || EEXISTS == ret)) { + /* Dataset has been created by another process, open it */ + if (iod_obj_open_write(coh, dset_id, NULL, &dset_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open Dataset"); + } + else if(!collective && 0 != ret) { + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create Dataset"); + } - /* 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); - } + /* for the process that succeeded in creating the dataset, update + the parent KV, create scratch pad */ + if(0 == ret) { + /* create the attribute KV object for the dataset */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &attr_id, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object"); + + /* create the metadata KV object for the dataset */ + 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 = attr_id; + sp.filler1_id = IOD_ID_UNDEFINED; + sp.filler2_id = IOD_ID_UNDEFINED; + + /* set scratch pad in dataset */ + if (iod_obj_set_scratch(dset_oh, IOD_TID_UNKNOWN, &sp, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set scratch pad"); + + /* Open Metadata KV object for write */ + 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"); + + if(H5P_DEFAULT == input->dcpl_id) + dcpl_id = H5P_DATASET_CREATE_DEFAULT; + else + dcpl_id = input->dcpl_id; + + /* insert plist metadata */ + if(H5VL_iod_insert_plist(mdkv_oh, IOD_TID_UNKNOWN, dcpl_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert link count metadata */ + if(H5VL_iod_insert_link_count(mdkv_oh, IOD_TID_UNKNOWN, (uint64_t)1, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert object type metadata */ + if(H5VL_iod_insert_object_type(mdkv_oh, IOD_TID_UNKNOWN, H5I_DATASET, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* MSC - need to check size of datatype if it fits in + entry otherwise create a BLOB*/ + /* insert datatype metadata */ + if(H5VL_iod_insert_datatype(mdkv_oh, IOD_TID_UNKNOWN, input->type_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert dataspace metadata */ + if(H5VL_iod_insert_dataspace(mdkv_oh, IOD_TID_UNKNOWN, input->space_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* close the Metadata KV object */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - #if H5_DO_NATIVE - cur_oh.cookie = H5Dcreate2(loc_handle.cookie, last_comp, input->type_id, - input->space_id, input->lcpl_id, - input->dcpl_id, input->dapl_id); - HDassert(cur_oh.cookie); - #endif + /* add link in parent group to current object */ + if(H5VL_iod_insert_new_link(cur_oh, IOD_TID_UNKNOWN, last_comp, dset_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + } - output.iod_oh = cur_oh; + /* 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 dset create, sending response to client\n"); - #endif +#if H5_DO_NATIVE + cur_oh.cookie = H5Dcreate2(loc_handle.cookie, last_comp, input->type_id, + input->space_id, input->lcpl_id, + input->dcpl_id, input->dapl_id); + assert(cur_oh.cookie); +#endif - HG_Handler_start_output(op_data->hg_handle, &output); + output.iod_oh = cur_oh; - done: - /* return an UNDEFINED oh to the client if the operation failed */ - if(ret_value < 0) { - output.iod_oh.cookie = IOD_OH_UNDEFINED; - HG_Handler_start_output(op_data->hg_handle, &output); - } +#if H5VL_IOD_DEBUG + fprintf(stderr, "Done with dset create, sending response to client\n"); +#endif + + HG_Handler_start_output(op_data->hg_handle, &output); - if(max_dims) free(max_dims); +done: + /* return an UNDEFINED oh to the client if the operation failed */ + if(ret_value < 0) { + output.iod_oh.cookie = IOD_OH_UNDEFINED; + HG_Handler_start_output(op_data->hg_handle, &output); + } + + if(max_dims) free(max_dims); if(array.current_dims) free(array.current_dims); - last_comp = (char *)H5MM_xfree(last_comp); - input = (dset_create_in_t *)H5MM_xfree(input); - op_data = (op_data_t *)H5MM_xfree(op_data); + last_comp = (char *)H5MM_xfree(last_comp); + input = (dset_create_in_t *)H5MM_xfree(input); + op_data = (op_data_t *)H5MM_xfree(op_data); - FUNC_LEAVE_NOAPI_VOID - } /* end H5VL_iod_server_dset_create_cb() */ + FUNC_LEAVE_NOAPI_VOID +} /* end H5VL_iod_server_dset_create_cb() */ - - /*------------------------------------------------------------------------- - * Function: H5VL_iod_server_dset_open_cb - * - * Purpose: Opens a dataset as a iod object. - * - * Return: Success: SUCCEED - * Failure: Negative - * - * Programmer: Mohamad Chaarawi - * February, 2013 - * - *------------------------------------------------------------------------- - */ - void - H5VL_iod_server_dset_open_cb(AXE_engine_t UNUSED axe_engine, - size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], - size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], - void *_op_data) - { - op_data_t *op_data = (op_data_t *)_op_data; - dset_open_in_t *input = (dset_open_in_t *)op_data->input; - dset_open_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; - iod_handle_t cur_oh, mdkv_oh; - iod_obj_id_t cur_id; - iod_obj_id_t dset_id; - char *name = input->name; - char *last_comp; - scratch_pad_t sp; - iod_size_t kv_size = sizeof(iod_obj_id_t); - herr_t ret_value = SUCCEED; + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_server_dset_open_cb + * + * Purpose: Opens a dataset as a iod object. + * + * Return: Success: SUCCEED + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * February, 2013 + * + *------------------------------------------------------------------------- + */ +void +H5VL_iod_server_dset_open_cb(AXE_engine_t UNUSED axe_engine, + size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], + size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], + void *_op_data) +{ + op_data_t *op_data = (op_data_t *)_op_data; + dset_open_in_t *input = (dset_open_in_t *)op_data->input; + dset_open_out_t output; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_obj_id_t dset_id; /* ID of the dataset to open */ + char *name = input->name; /* name of dset including path to open */ + char *last_comp; /* the name of the dataset obtained from the last component in the path */ + iod_handle_t cur_oh, mdkv_oh; + iod_obj_id_t cur_id; + scratch_pad_t sp; + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI_NOINIT - #if H5VL_IOD_DEBUG - fprintf(stderr, "Start dataset Open %s\n", name); - #endif +#if H5VL_IOD_DEBUG + fprintf(stderr, "Start dataset Open %s\n", name); +#endif - /* the traversal will retrieve the location where the dataset needs - to be opened. 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"); - - if(iod_kv_get_value(cur_oh, IOD_TID_UNKNOWN, last_comp, &dset_id, - kv_size , NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Array ID from parent KV store"); - - /* 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); - } + /* the traversal will retrieve the location where the dataset needs + to be opened. 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"); + + if(iod_kv_get_value(cur_oh, IOD_TID_UNKNOWN, last_comp, &dset_id, + sizeof(iod_obj_id_t), NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve Array ID from parent KV store"); + + /* 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 dataset */ - if (iod_obj_open_write(coh, dset_id, NULL /*hints*/, &cur_oh, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open dataset"); - - /* get scratch pad of the dataset */ - 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"); - - #if 0 - /* MSC - retrieve all metadata from scratch pad */ - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dcpl", NULL, - &output.dcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dcpl lookup failed"); - if(NULL == (output.dcpl = H5MM_malloc (output.dcpl_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dcpl buffer"); - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dcpl", output.dcpl, - &output.dcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dcpl lookup failed"); - - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dtype", NULL, - &output.dtype_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dtype lookup failed"); - if(NULL == (output.dtype = H5MM_malloc (output.dtype_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dtype buffer"); - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dtype", output.dtype, - &output.dtype_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dtype lookup failed"); - - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dspace", NULL, - &output.dspace_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dspace lookup failed"); - if(NULL == (output.dspace = H5MM_malloc (output.dspace_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate dspace buffer"); - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_dspace", output.dspace, - &output.dspace_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dspace lookup failed"); - #endif + /* open the dataset */ + if (iod_obj_open_write(coh, dset_id, NULL /*hints*/, &cur_oh, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open dataset"); - /* close the metadata scratch pad */ - if(iod_obj_close(mdkv_oh, NULL, NULL)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + /* get scratch pad of the dataset */ + 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"); - { - hsize_t dims[1]; - //hid_t space_id, type_id; + /* 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"); - #if H5_DO_NATIVE - printf("dataset name %s location %d\n", name, loc_handle.cookie); - cur_oh.cookie = H5Dopen(loc_handle.cookie, name, input->dapl_id); - HDassert(cur_oh.cookie); - output.space_id = H5Dget_space(cur_oh.cookie); - output.type_id = H5Dget_type(cur_oh.cookie); - output.dcpl_id = H5P_DATASET_CREATE_DEFAULT; - #else - /* fake a dataspace, type, and dcpl */ - dims [0] = 60; - output.space_id = H5Screate_simple(1, dims, NULL); - output.type_id = H5Tcopy(H5T_NATIVE_INT); - output.dcpl_id = H5P_DATASET_CREATE_DEFAULT; - cur_oh.cookie = 1; - #endif + /* MSC - retrieve metadata - NEED IOD */ +#if 0 + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_PLIST, "create_plist", + NULL, NULL, NULL, &output.dcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dcpl"); - #if 0 - output.dcpl_size = 0; - output.dcpl = NULL; - - /* get Type size to encode */ - if(H5Tencode(type_id, NULL, &output.dtype_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset type"); - if(NULL == (output.dtype = H5MM_malloc (output.dtype_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate datatype buffer"); - if(H5Tencode(type_id, output.dtype, &output.dtype_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype"); - - /* get Dataspace size to encode */ - if(H5Sencode(space_id, NULL, &output.dspace_size)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace"); - if(NULL == (output.dspace = H5MM_malloc (output.dspace_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate datatype buffer"); - if(H5Sencode(space_id, output.dspace, &output.dspace_size) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace"); - - H5Sclose(space_id); - #endif + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_LINK_COUNT, "link_count", + NULL, NULL, NULL, &output.link_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count"); - } + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATATYPE, "datatype", + NULL, NULL, NULL, &output.type_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve datatype"); - dset_id = 1; - output.iod_id = dset_id; - output.iod_oh.cookie = cur_oh.cookie; + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_DATASPACE, "dataspace", + NULL, NULL, NULL, &output.space_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve dataspace"); +#endif - #if H5VL_IOD_DEBUG - fprintf(stderr, "Done with dset open, sending response to client\n"); - #endif + /* close the metadata scratch pad */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - HG_Handler_start_output(op_data->hg_handle, &output); + { + hsize_t dims[1]; + //hid_t space_id, type_id; - 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); - } +#if H5_DO_NATIVE + printf("dataset name %s location %d\n", name, loc_handle.cookie); + cur_oh.cookie = H5Dopen(loc_handle.cookie, name, input->dapl_id); + HDassert(cur_oh.cookie); + output.space_id = H5Dget_space(cur_oh.cookie); + output.type_id = H5Dget_type(cur_oh.cookie); + output.dcpl_id = H5P_DATASET_CREATE_DEFAULT; +#else + /* fake a dataspace, type, and dcpl */ + dims [0] = 60; + output.space_id = H5Screate_simple(1, dims, NULL); + output.type_id = H5Tcopy(H5T_NATIVE_INT); + output.dcpl_id = H5P_DATASET_CREATE_DEFAULT; + cur_oh.cookie = 1; +#endif - H5Tclose(output.type_id); - H5Sclose(output.space_id); +#if 0 + output.dcpl_size = 0; + output.dcpl = NULL; + + /* get Type size to encode */ + if(H5Tencode(type_id, NULL, &output.dtype_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode dataset type"); + if(NULL == (output.dtype = H5MM_malloc (output.dtype_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate datatype buffer"); + if(H5Tencode(type_id, output.dtype, &output.dtype_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype"); + + /* get Dataspace size to encode */ + if(H5Sencode(space_id, NULL, &output.dspace_size)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace"); + if(NULL == (output.dspace = H5MM_malloc (output.dspace_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate datatype buffer"); + if(H5Sencode(space_id, output.dspace, &output.dspace_size) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace"); + + H5Sclose(space_id); +#endif - input = (dset_open_in_t *)H5MM_xfree(input); - op_data = (op_data_t *)H5MM_xfree(op_data); - last_comp = (char *)H5MM_xfree(last_comp); + } - FUNC_LEAVE_NOAPI_VOID - } /* end H5VL_iod_server_dset_open_cb() */ + dset_id = 1; + output.iod_id = dset_id; + output.iod_oh.cookie = cur_oh.cookie; + +#if H5VL_IOD_DEBUG + fprintf(stderr, "Done with dset open, sending response to client\n"); +#endif + + HG_Handler_start_output(op_data->hg_handle, &output); + +done: + if(ret_value < 0) { + output.iod_oh.cookie = IOD_OH_UNDEFINED; + output.iod_id = IOD_ID_UNDEFINED; + HG_Handler_start_output(op_data->hg_handle, &output); + } + + H5Tclose(output.type_id); + H5Sclose(output.space_id); + + input = (dset_open_in_t *)H5MM_xfree(input); + op_data = (op_data_t *)H5MM_xfree(op_data); + last_comp = (char *)H5MM_xfree(last_comp); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5VL_iod_server_dset_open_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_iod_server_dset_read_cb + * + * Purpose: Reads from IOD into the function shipper BDS handle. + * + * Return: Success: SUCCEED + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2013 + * + *------------------------------------------------------------------------- + */ +void +H5VL_iod_server_dset_read_cb(AXE_engine_t UNUSED axe_engine, + size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], + size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], + void *_op_data) +{ + op_data_t *op_data = (op_data_t *)_op_data; + dset_io_in_t *input = (dset_io_in_t *)op_data->input; + dset_read_out_t output; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t iod_oh = input->iod_oh; /* dset object handle */ + iod_obj_id_t iod_id = input->iod_id; /* dset ID */ + hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */ + hid_t space_id = input->space_id; /* file space selection */ + hid_t dxpl_id = input->dxpl_id; /* transfer property list */ + hid_t src_id = input->dset_type_id; /* the datatype of the dataset's element */ + hid_t dst_id = input->mem_type_id; /* the memory type of the elements */ + hg_bulk_block_t bulk_block_handle; /* HG block handle */ + hg_bulk_request_t bulk_request; /* HG request */ + iod_mem_desc_t mem_desc; /* memory descriptor used for reading array */ + iod_array_iodesc_t file_desc; /* file descriptor used to read array */ + iod_hyperslab_t *hslabs = NULL; /* IOD hyperslab generated from HDF5 filespace */ + size_t size, buf_size, src_size, dst_size; + void *buf; /* buffer to hold outgoing data */ + uint8_t *buf_ptr; + hssize_t num_descriptors = 0, n; /* number of IOD file descriptors needed to describe filespace selection */ + int ndims, i; /* dataset's rank/number of dimensions */ + uint32_t cs = 0; /* checksum value */ + size_t nelmts; /* number of elements selected to read */ + na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); /* destination address to push data to */ + hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the dset here or if it was already open */ + herr_t ret_value = SUCCEED; - - /*------------------------------------------------------------------------- - * Function: H5VL_iod_server_dset_read_cb - * - * Purpose: Reads from IOD into the function shipper BDS handle. - * - * Return: Success: SUCCEED - * Failure: Negative - * - * Programmer: Mohamad Chaarawi - * January, 2013 - * - *------------------------------------------------------------------------- - */ - void - H5VL_iod_server_dset_read_cb(AXE_engine_t UNUSED axe_engine, - size_t UNUSED num_n_parents, AXE_task_t UNUSED n_parents[], - size_t UNUSED num_s_parents, AXE_task_t UNUSED s_parents[], - void *_op_data) - { - op_data_t *op_data = (op_data_t *)_op_data; - dset_io_in_t *input = (dset_io_in_t *)op_data->input; - dset_read_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t iod_oh = input->iod_oh; - iod_obj_id_t iod_id = input->iod_id; - hg_bulk_t bulk_handle = input->bulk_handle; - hid_t space_id = input->space_id; - hid_t dxpl_id = input->dxpl_id; - hid_t src_id = input->dset_type_id; - hid_t dst_id = input->mem_type_id; - hg_bulk_block_t bulk_block_handle; - hg_bulk_request_t bulk_request; - iod_mem_desc_t mem_desc; - iod_array_iodesc_t file_desc; - iod_hyperslab_t *hslabs = NULL; - size_t size, buf_size, src_size, dst_size; - void *buf; - uint8_t *buf_ptr; - hssize_t num_descriptors = 0, n; - int ndims, i; - uint32_t cs = 0; - size_t nelmts; - na_addr_t dest = HG_Handler_get_addr(op_data->hg_handle); - hbool_t opened_locally = FALSE; - herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -736,7 +708,6 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) { - int ret_value = CP_SUCCESS; int i, *ptr = NULL, request_counter= 0; int ndims; @@ -773,6 +744,7 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) #if DEBUG_COMPACTOR fprintf (stderr,"Entering COMPACTOR WRITE with requests %d\n", num_requests); #endif + for (request_counter = 0; request_counter < num_requests; request_counter++){ if (list[request_counter].merged != USED_IN_MERGING){ @@ -788,7 +760,6 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) bulk_handle = input->bulk_handle; space_id = list[request_counter].selection_id; dst_id = input->dset_type_id; - dst_size = H5Tget_size(dst_id); fprintf (stderr,"COMPACTOR space_id: %d, selection_id: %d\n", space_id, list[request_counter].selection_id); @@ -824,17 +795,19 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) /*Even in the case its not merged the buffer was already extracted*/ fprintf (stderr,"COMPACTOR WRITE: Request %d has been merged \n", request_counter+1); } - + + dst_size = H5Tget_size(dst_id); + if(iod_oh.cookie == (int)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; } - + /* get the rank of the dataspace */ if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataspace dimesnsion"); - + /* get the number of decriptors required, i.e. the numbers of iod I/O operations needed */ if(H5VL_iod_get_file_desc(space_id, &num_descriptors, NULL) < 0) @@ -870,32 +843,20 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) } } #endif - curr_j = 0; + curr_j = 0; for(n=0 ; n<num_descriptors ; n++) { - - fprintf (stderr, - "COMPACTOR WRITE num_descriptors : %llu, n : %llu\n", - num_descriptors, n); - - num_bytes = 0; - num_elems = 1; - - /* determine how many bytes the current descriptor holds */ - for(i=0 ; i<ndims ; i++){ - num_elems *= (hslabs[n].count[i] * hslabs[n].block[i]); - } - num_bytes = num_elems * dst_size; - - fprintf (stderr, - "COMPACTOR WRITE num_elems : %lli, num_bytes: %lli, dst_size: %zd\n", - num_elems, - num_bytes, - dst_size); + num_bytes = 0; + num_elems = 1; + + /* determine how many bytes the current descriptor holds */ + for(i=0 ; i<ndims ; i++) + num_elems *= (hslabs[n].count[i] * hslabs[n].block[i]); + num_bytes = num_elems * dst_size; if (list[request_counter].merged == NOT_MERGED){ - + buf_ptr = (uint8_t *)buf; #if 1 /* set the memory descriptor */ @@ -904,8 +865,9 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) mem_desc->nfrag = 1; mem_desc->frag[0].addr = (void *)buf_ptr; mem_desc->frag[0].len = (iod_size_t)num_bytes; -#endif buf_ptr += num_bytes; + +#endif if (NULL != buf){ free(buf); @@ -913,6 +875,7 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) } if (list[request_counter].merged == MERGED){ + #if DEBUG_COMPACTOR fprintf (stderr, "COMPACTOR WRITE i: %d, num_mblocks: %zd, num_bytes: %lli\n", request_counter, list[request_counter].num_mblocks, num_bytes); @@ -927,7 +890,7 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) curr_j, j, list[request_counter].num_mblocks); for (j = curr_j; j < list[request_counter].num_mblocks; j++){ - + if (k < num_bytes){ if (bytes_left){ @@ -951,7 +914,8 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) } } - fprintf (stderr,"COMPACTOR WRITE k: %lli mem_reqs: %lli start_reqs: %lli, curr_j: %lli\n", + fprintf (stderr, + "COMPACTOR WRITE k: %lli mem_reqs: %lli start_reqs: %lli, curr_j: %lli\n", k, mem_reqs, start_reqs, @@ -961,24 +925,29 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) descriptor*/ mem_desc = (iod_mem_desc_t *) malloc (sizeof(iod_mem_desc_t)); mem_desc->nfrag = mem_reqs; - mem_desc->frag = (iod_mem_frag_t *) malloc ((int)mem_reqs * sizeof(iod_mem_frag_t)); + mem_desc->frag = + (iod_mem_frag_t *) malloc ((int)mem_reqs * sizeof(iod_mem_frag_t)); k = curr_k; + fprintf (stderr,"COMPACTOR WRITE start_reqs: %lli, mem_reqs: %lli\n", start_reqs, mem_reqs); for ( j = start_reqs; j < mem_reqs; j++){ if ((j == curr_j) && (bytes_left)){ - mem_desc->frag[k].addr = (void *)(uintptr_t)(curr_offset); + mem_desc->frag[k].addr = (void *)(uintmax_t)(curr_offset); mem_desc->frag[k].len = bytes_left; } else{ - mem_desc->frag[k].addr = (void *)(uintptr_t)(list[request_counter].mblocks[j].offset); + mem_desc->frag[k].addr = + (uint64_t *)(list[request_counter].mblocks[j].offset); mem_desc->frag[k].len = list[request_counter].mblocks[j].len; - fprintf(stderr,"COMPACTOR %lli: off: %ld, off: %lli len: %llu\n", +#if 0 + fprintf(stderr,"COMPACTOR %lli: off: %lli, off: %lli len: %llu\n", k, - (long int)mem_desc->frag[k].addr, + (hsize_t)mem_desc->frag[k].addr, list[request_counter].mblocks[j].offset, mem_desc->frag[k].len); +#endif } k++; } @@ -994,7 +963,7 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) (size_t)file_desc.block[i], (size_t)file_desc.count[i]); } #endif - + if(iod_array_write(iod_oh, IOD_TID_UNKNOWN, NULL, mem_desc /*This is where the memory descriptor goes*/, &file_desc, @@ -1019,20 +988,18 @@ int H5VL_iod_server_compactor_write (void *_list, int num_requests) } /* write from array object */ - /* TODO: VV Change checksum once that is fixed*/ - - + /* TODO: VV Change checksum once that is fixed*/ 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 dset write, sending %d response to client\n", ret_value); #endif - /* free allocated descriptors */ } for (i = 0; i< num_requests; i++){ @@ -1073,30 +1040,30 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, { op_data_t *op_data = (op_data_t *)_op_data; dset_io_in_t *input = (dset_io_in_t *)op_data->input; - iod_handle_t coh = input->coh; - iod_handle_t iod_oh = input->iod_oh; - iod_obj_id_t iod_id = input->iod_id; - hg_bulk_t bulk_handle = input->bulk_handle; - hid_t space_id = input->space_id; - hid_t dxpl_id = input->dxpl_id; - uint32_t cs = input->checksum; - hid_t src_id = input->mem_type_id; - hid_t dst_id = input->dset_type_id; - uint32_t data_cs = 0; - hg_bulk_block_t bulk_block_handle; - hg_bulk_request_t bulk_request; - iod_mem_desc_t mem_desc; - iod_array_iodesc_t file_desc; - iod_hyperslab_t *hslabs = NULL; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t iod_oh = input->iod_oh; /* dset object handle */ + iod_obj_id_t iod_id = input->iod_id; /* dset ID */ + hg_bulk_t bulk_handle = input->bulk_handle; /* bulk handle for data */ + hid_t space_id = input->space_id; /* file space selection */ + hid_t dxpl_id = input->dxpl_id; /* transfer property list */ + uint32_t cs = input->checksum; /* checksum recieved for data */ + hid_t src_id = input->mem_type_id; /* the memory type of the elements */ + hid_t dst_id = input->dset_type_id; /* the datatype of the dataset's element */ + hg_bulk_block_t bulk_block_handle; /* HG block handle */ + hg_bulk_request_t bulk_request; /* HG request */ + iod_mem_desc_t mem_desc; /* memory descriptor used for writing array */ + iod_array_iodesc_t file_desc; /* file descriptor used to write array */ + iod_hyperslab_t *hslabs = NULL; /* IOD hyperslab generated from HDF5 filespace */ size_t size, buf_size, src_size, dst_size; - hssize_t num_descriptors = 0, n; - int ndims, i; + uint32_t data_cs = 0; + hssize_t num_descriptors = 0, n; /* number of IOD file descriptors needed to describe filespace selection */ + int ndims, i; /* dataset's rank/number of dimensions */ void *buf; uint8_t *buf_ptr; - size_t nelmts; - hbool_t flag = FALSE; - na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); - hbool_t opened_locally = FALSE; + size_t nelmts; /* number of elements selected to write */ + hbool_t flag = FALSE; /* temp flag to indicate whether corruption will be inserted */ + na_addr_t source = HG_Handler_get_addr(op_data->hg_handle); /* source address to pull data from */ + hbool_t opened_locally = FALSE; /* flag to indicate whether we opened the dset here or if it was already open */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -1117,6 +1084,7 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, fprintf(stderr, "Size: %zd\n" ,size); nelmts = (size_t)H5Sget_select_npoints(space_id); + src_size = H5Tget_size(src_id); dst_size = H5Tget_size(dst_id); @@ -1143,7 +1111,7 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, if(HG_SUCCESS != HG_Bulk_read_all(source, bulk_handle, bulk_block_handle, &bulk_request)) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper"); /* wait for it to complete */ - if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_BULK_MAX_IDLE_TIME, HG_BULK_STATUS_IGNORE)) + if(HG_SUCCESS != HG_Bulk_wait(bulk_request, HG_MAX_IDLE_TIME, HG_STATUS_IGNORE)) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't get data from function shipper"); /* free the bds block handle */ @@ -1177,7 +1145,8 @@ 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<size/4;++i) + + for(i=0 ; i<size/sizeof(int) ; ++i) fprintf(stderr, "%d ", ptr[i]); fprintf(stderr, "\n"); } @@ -1213,7 +1182,7 @@ H5VL_iod_server_dset_write_cb(AXE_engine_t UNUSED axe_engine, /* write each descriptore to the IOD container */ for(n=0 ; n<num_descriptors ; n++) { hsize_t num_bytes = 0; - hsize_t num_elems = 0; + hsize_t num_elems = 1; /* determine how many bytes the current descriptor holds */ for(i=0 ; i<ndims ; i++) @@ -1279,7 +1248,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() */ @@ -1309,7 +1278,7 @@ H5VL_iod_server_dset_set_extent_cb(AXE_engine_t UNUSED axe_engine, iod_handle_t coh = input->coh; iod_handle_t iod_oh = input->iod_oh; iod_obj_id_t iod_id = input->iod_id; - int rank = input->dims.rank; + int rank = input->dims.rank; /* rank of dataset */ hbool_t opened_locally = FALSE; herr_t ret_value = SUCCEED; @@ -1394,7 +1363,7 @@ H5VL_iod_server_dset_close_cb(AXE_engine_t UNUSED axe_engine, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); } else { - /* MSC - need a way to kill object handle for this group */ + /* MSC - need a way to kill object handle for this dataset */ fprintf(stderr, "I do not have the OH of this dataset to close it\n"); } diff --git a/src/H5VLiod_dtype.c b/src/H5VLiod_dtype.c index 06585e8..264ab27 100644 --- a/src/H5VLiod_dtype.c +++ b/src/H5VLiod_dtype.c @@ -47,22 +47,22 @@ H5VL_iod_server_dtype_commit_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; dtype_commit_in_t *input = (dtype_commit_in_t *)op_data->input; dtype_commit_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ iod_obj_id_t dtype_id = input->dtype_id; /* The ID of the datatype that needs to be created */ iod_handle_t dtype_oh, cur_oh, mdkv_oh; - iod_obj_id_t cur_id, mdkv_id; - const char *name = input->name; - iod_kv_t kv; + iod_obj_id_t cur_id, mdkv_id, attr_id; + const char *name = input->name; /* name of dtype including path to commit */ + hid_t tcpl_id; char *last_comp; /* the name of the datatype obtained from the last component in the path */ - size_t buf_size; + size_t buf_size; /* size of the serialized datatype */ void *buf; - iod_mem_desc_t mem_desc; - iod_blob_iodesc_t file_desc; + iod_mem_desc_t mem_desc; /* memory descriptor used for writing */ + iod_blob_iodesc_t file_desc; /* file descriptor used to write */ scratch_pad_t sp; iod_ret_t ret; - hbool_t collective = FALSE; /* MSC - change when we allow for collective */ + hbool_t collective = FALSE; /* flag to indicate whether we opened the attribute here or if it was already open */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -98,9 +98,14 @@ H5VL_iod_server_dtype_commit_cb(AXE_engine_t UNUSED axe_engine, NULL, NULL, &mdkv_id, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object"); + /* create the attribute KV object for the datatype */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &attr_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.attr_id = attr_id; sp.filler1_id = IOD_ID_UNDEFINED; sp.filler2_id = IOD_ID_UNDEFINED; @@ -137,50 +142,57 @@ H5VL_iod_server_dtype_commit_cb(AXE_engine_t UNUSED axe_engine, if(iod_blob_write(dtype_oh, IOD_TID_UNKNOWN, NULL, &mem_desc, &file_desc, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object"); - /* MSC - TODO store things */ -#if 0 - /* insert datatype metadata into scratch pad */ - - kv.key = HDstrdup("datatype_tcpl"); - /* determine the buffer size needed to store the encoded tcpl of the datatype */ - if(H5Pencode(input->tcpl_id, NULL, &value_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode datatype tcpl"); - if(NULL == (kv.value = malloc (value_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate tcpl buffer"); - /* encode tcpl of the datatype */ - if(H5Pencode(input->tcpl_id, kv.value, &value_size) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode datatype tcpl"); - kv.value_len = (iod_size_t)value_size; - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); - - kv.key = HDstrdup("datatype_size"); - kv.value_len = sizeof(iod_size_t); - if(NULL == (kv.value = malloc (kv.value_len))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); - memcpy(kv.value, &buf_size, kv.value_len); - - /* insert kv pair into scratch pad */ - if (iod_kv_set(mdkv_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); - free(kv.value); -#endif + + if(H5P_DEFAULT == input->tcpl_id) + tcpl_id = H5P_DATATYPE_CREATE_DEFAULT; + else + tcpl_id = input->tcpl_id; + + /* insert plist metadata */ + if(H5VL_iod_insert_plist(mdkv_oh, IOD_TID_UNKNOWN, tcpl_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert link count metadata */ + if(H5VL_iod_insert_link_count(mdkv_oh, IOD_TID_UNKNOWN, (uint64_t)1, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert object type metadata */ + if(H5VL_iod_insert_object_type(mdkv_oh, IOD_TID_UNKNOWN, H5I_DATATYPE, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* store the datatype size */ + { + iod_kv_t kv; + char *key = NULL; + char *value = NULL; + + key = strdup("size"); + kv.key = key; + kv.value_len = sizeof(iod_size_t); + + if(NULL == (value = malloc (kv.value_len))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + *((int32_t *)value) = buf_size; + kv.value = value; + + if (iod_kv_set(mdkv_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + + free(key); + free(value); + } /* close the Metadata KV object */ if(iod_obj_close(mdkv_oh, NULL, NULL)) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - kv.key = HDstrdup(last_comp); - kv.value = &dtype_id; - kv.value_len = sizeof(iod_obj_id_t); - /* insert new datatype in kv store of current group */ - 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); + /* add link in parent group to current object */ + if(H5VL_iod_insert_new_link(cur_oh, IOD_TID_UNKNOWN, last_comp, dtype_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); } #if H5_DO_NATIVE cur_oh.cookie = H5Tcopy(input->type_id); @@ -242,18 +254,18 @@ H5VL_iod_server_dtype_open_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; dtype_open_in_t *input = (dtype_open_in_t *)op_data->input; dtype_open_out_t output; - iod_handle_t coh = input->coh; - iod_handle_t loc_handle = input->loc_oh; - iod_obj_id_t loc_id = input->loc_id; - iod_obj_id_t dtype_id; + iod_handle_t coh = input->coh; /* container handle */ + iod_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + iod_obj_id_t dtype_id; /* ID of datatype to open */ iod_handle_t cur_oh, mdkv_oh; iod_obj_id_t cur_id, mdkv_id; - const char *name = input->name; + const char *name = input->name; /* name of dtype including path to open */ char *last_comp; /* the name of the datatype obtained from the last component in the path */ - size_t buf_size; - void *buf; - iod_mem_desc_t mem_desc; - iod_blob_iodesc_t file_desc; + size_t buf_size; /* size of serialized datatype */ + void *buf = NULL; + iod_mem_desc_t mem_desc; /* memory descriptor used for reading */ + iod_blob_iodesc_t file_desc; /* file descriptor used to write */ iod_size_t kv_size = sizeof(iod_obj_id_t); scratch_pad_t sp; herr_t ret_value = SUCCEED; @@ -285,29 +297,30 @@ H5VL_iod_server_dtype_open_cb(AXE_engine_t UNUSED axe_engine, 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 - need to read datatype; size should be stored in metadata, - but since no real IOD, can't do anything now */ - #if 0 - /*retrieve tcpl metadata from scratch pad */ - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "datatype_tcpl", NULL, - &output.tcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "datatype tcpl lookup failed"); - if(NULL == (output.tcpl = H5MM_malloc (output.tcpl_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate tcpl buffer"); - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "datatype_tcpl", output.tcpl, - &output.tcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "datatype tcpl lookup failed"); - - /*retrieve blob size metadata from scratch pad */ - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "datatype_size", &buf_size, + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_PLIST, "create_plist", + NULL, NULL, NULL, &output.tcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve tcpl"); + + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_LINK_COUNT, "link_count", + NULL, NULL, NULL, &output.link_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count"); + + /* retrieve blob size metadata from scratch pad */ + if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "size", &buf_size, sizeof(iod_size_t), NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "datatype size lookup failed"); if(NULL == (buf = malloc(buf_size))) HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate BLOB read buffer"); +#endif - /* create memory descriptor for writing */ + /* close the metadata scratch pad */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + +#if 0 + /* create memory descriptor for reading */ mem_desc.nfrag = 1; mem_desc.frag->addr = buf; mem_desc.frag->len = (iod_size_t)buf_size; @@ -317,8 +330,8 @@ H5VL_iod_server_dtype_open_cb(AXE_engine_t UNUSED axe_engine, file_desc.frag->offset = 0; file_desc.frag->len = (iod_size_t)buf_size; - /* write the serialized type value to the BLOB object */ - if(iod_blob_write(cur_oh, IOD_TID_UNKNOWN, NULL, &mem_desc, &file_desc, NULL, NULL) < 0) + /* read the serialized type value from the BLOB object */ + if(iod_blob_read(cur_oh, IOD_TID_UNKNOWN, NULL, &mem_desc, &file_desc, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write BLOB object"); /* decode the datatype */ @@ -328,10 +341,6 @@ H5VL_iod_server_dtype_open_cb(AXE_engine_t UNUSED axe_engine, free(buf); #endif - /* close the metadata scratch pad */ - if(iod_obj_close(mdkv_oh, NULL, NULL)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - #if H5_DO_NATIVE printf("datatype name %s location %d\n", name, loc_handle.cookie); cur_oh.cookie = H5Topen(loc_handle.cookie, name, input->tapl_id); diff --git a/src/H5VLiod_encdec.c b/src/H5VLiod_encdec.c index c342984..8ec916f 100644 --- a/src/H5VLiod_encdec.c +++ b/src/H5VLiod_encdec.c @@ -207,7 +207,7 @@ 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; @@ -215,8 +215,9 @@ 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 +236,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 +401,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_file.c b/src/H5VLiod_file.c index 3dc9a3e..febc379 100644 --- a/src/H5VLiod_file.c +++ b/src/H5VLiod_file.c @@ -49,10 +49,11 @@ H5VL_iod_server_file_create_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; file_create_in_t *input = (file_create_in_t *)op_data->input; file_create_out_t output; - unsigned int mode; - iod_handle_t coh; - iod_handle_t root_oh, mdkv_oh; - iod_obj_id_t mdkv_id; + unsigned int mode; /* create mode */ + iod_handle_t coh; /* container handle */ + iod_handle_t root_oh; /* root object handle */ + iod_handle_t mdkv_oh; /* metadata object handle for KV to store file's metadata */ + iod_obj_id_t mdkv_id, attr_id; /* metadata and attribute KV IDs for the file */ iod_ret_t ret; herr_t ret_value = SUCCEED; @@ -87,15 +88,26 @@ H5VL_iod_server_file_create_cb(AXE_engine_t UNUSED axe_engine, the scratch pad for it too */ if(0 == ret) { scratch_pad_t sp; + iod_kv_t kv; + void *key = NULL; + void *value = NULL; + size_t buf_size; + hid_t fcpl_id; + uint64_t index; /* create the metadata KV object for the root group */ 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"); + /* create the attribute KV object for the root group */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &attr_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.attr_id = attr_id; sp.filler1_id = IOD_ID_UNDEFINED; sp.filler2_id = IOD_ID_UNDEFINED; @@ -107,7 +119,48 @@ H5VL_iod_server_file_create_cb(AXE_engine_t UNUSED axe_engine, 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 */ + /* store metadata */ + + + if(H5P_DEFAULT == input->fcpl_id) + fcpl_id = H5P_FILE_CREATE_DEFAULT; + else + fcpl_id = input->fcpl_id; + + /* insert plist metadata */ + if(H5VL_iod_insert_plist(mdkv_oh, IOD_TID_UNKNOWN, fcpl_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert link count KV value"); + + /* insert initial indexes for IOD IDs */ + if(NULL == (value = malloc (sizeof(uint64_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + *((uint64_t *)value) = 1; + kv.value_len = sizeof(uint64_t); + + key = strdup("kv_index"); + kv.key = (char *)key; + if (iod_kv_set(mdkv_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + free(key); + key = NULL; + + key = strdup("array_index"); + kv.key = (char *)key; + if (iod_kv_set(mdkv_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + free(key); + key = NULL; + + key = strdup("blob_index"); + kv.key = (char *)key; + if (iod_kv_set(mdkv_oh, IOD_TID_UNKNOWN, NULL, &kv, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + free(key); + key = NULL; + + free(value); + value = NULL; if(iod_obj_close(mdkv_oh, NULL, NULL)) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close root object handle"); @@ -171,9 +224,10 @@ H5VL_iod_server_file_open_cb(AXE_engine_t UNUSED axe_engine, op_data_t *op_data = (op_data_t *)_op_data; file_open_in_t *input = (file_open_in_t *)op_data->input; file_open_out_t output; - unsigned int mode = input->flags; - iod_handle_t coh; - iod_handle_t root_oh, mdkv_oh; + unsigned int mode = input->flags; /* File Open mode */ + iod_handle_t coh; /* container handle */ + iod_handle_t root_oh; /* root object handle */ + iod_handle_t mdkv_oh; /* metadata object handle for KV to store file's metadata */ scratch_pad_t sp; herr_t ret_value = SUCCEED; @@ -199,12 +253,32 @@ H5VL_iod_server_file_open_cb(AXE_engine_t UNUSED axe_engine, 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 */ + /* retrieve all metadata from scratch pad */ + /* MSC - fake for now */ output.kv_oid_index = 1; output.array_oid_index = 1; output.blob_oid_index = 1; output.fcpl_id = H5P_FILE_CREATE_DEFAULT; + /* MSC - NEED IOD */ +#if 0 + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_PLIST, "create_plist", + NULL, NULL, NULL, &output.fcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve fcpl"); + + if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "kv_index", &output.kv_oid_index, + sizeof(uint64_t), NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "KV index lookup failed"); + + if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "array_index", &output.array_oid_index, + sizeof(uint64_t), NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Array index lookup failed"); + + if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "blob_index", &output.blob_oid_index, + sizeof(uint64_t), NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "BLOB index lookup failed"); +#endif + /* close the metadata scratch pad */ if(iod_obj_close(mdkv_oh, NULL, NULL)) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close root object handle"); @@ -212,7 +286,7 @@ H5VL_iod_server_file_open_cb(AXE_engine_t UNUSED axe_engine, #if H5_DO_NATIVE { coh.cookie = H5Fopen(input->name, H5F_ACC_RDWR, H5P_DEFAULT); - HDassert(coh.cookie); + assert(coh.cookie); root_oh.cookie = coh.cookie; fprintf(stderr, "Opened Native file %s with ID %d\n", input->name, root_oh.cookie); } diff --git a/src/H5VLiod_group.c b/src/H5VLiod_group.c index c50e902..018457d 100644 --- a/src/H5VLiod_group.c +++ b/src/H5VLiod_group.c @@ -55,9 +55,9 @@ H5VL_iod_server_group_create_cb(AXE_engine_t UNUSED axe_engine, iod_obj_id_t grp_id = input->grp_id; /* The ID of the group that needs to be created */ const char *name = input->name; /* path relative to loc_id and loc_oh */ iod_handle_t grp_oh, cur_oh, mdkv_oh; - iod_obj_id_t cur_id, mdkv_id; + iod_obj_id_t cur_id, mdkv_id, attr_id; char *last_comp; /* the name of the group obtained from traversal function */ - iod_kv_t kv; + hid_t gcpl_id; scratch_pad_t sp; iod_ret_t ret; hbool_t collective = FALSE; /* MSC - change when we allow for collective */ @@ -96,9 +96,14 @@ H5VL_iod_server_group_create_cb(AXE_engine_t UNUSED axe_engine, NULL, NULL, &mdkv_id, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create metadata KV object"); + /* create the attribute KV object for the group */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &attr_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.attr_id = attr_id; sp.filler1_id = IOD_ID_UNDEFINED; sp.filler2_id = IOD_ID_UNDEFINED; @@ -106,22 +111,39 @@ H5VL_iod_server_group_create_cb(AXE_engine_t UNUSED axe_engine, if (iod_obj_set_scratch(grp_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 */ + /* store metadata */ + /* Open Metadata KV object for write */ 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(H5P_DEFAULT == input->gcpl_id) + gcpl_id = H5P_GROUP_CREATE_DEFAULT; + else + gcpl_id = input->gcpl_id; + + /* insert plist metadata */ + if(H5VL_iod_insert_plist(mdkv_oh, IOD_TID_UNKNOWN, gcpl_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + /* insert link count metadata */ + if(H5VL_iod_insert_link_count(mdkv_oh, IOD_TID_UNKNOWN, (uint64_t)1, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert object type metadata */ + if(H5VL_iod_insert_object_type(mdkv_oh, IOD_TID_UNKNOWN, H5I_GROUP, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* close Metadata KV object */ if(iod_obj_close(mdkv_oh, NULL, NULL)) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); - /* insert new group in kv store of parent object */ - kv.key = HDstrdup(last_comp); - kv.value = &grp_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); + /* add link in parent group to current object */ + if(H5VL_iod_insert_new_link(cur_oh, IOD_TID_UNKNOWN, last_comp, grp_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); } /* end if */ /* close parent group if it is not the location we started the @@ -132,7 +154,7 @@ H5VL_iod_server_group_create_cb(AXE_engine_t UNUSED axe_engine, #if H5_DO_NATIVE grp_oh.cookie = H5Gcreate2(loc_handle.cookie, name, input->lcpl_id, - input->gcpl_id, input->gapl_id); + input->gcpl_id, input->gapl_id); HDassert(grp_oh.cookie); #endif @@ -183,12 +205,12 @@ H5VL_iod_server_group_open_cb(AXE_engine_t UNUSED axe_engine, group_open_in_t *input = (group_open_in_t *)op_data->input; group_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_handle_t loc_handle = input->loc_oh; /* location handle to start lookup */ + iod_obj_id_t loc_id = input->loc_id; /* The ID of the current location object */ + const char *name = input->name; /* group name including path to open */ iod_obj_id_t grp_id; /* The ID of the group that needs to be opened */ iod_handle_t cur_oh, mdkv_oh; - iod_obj_id_t cur_id, mdkv_id; + iod_obj_id_t cur_id; char *last_comp; /* the name of the group obtained from traversal function */ iod_size_t kv_size; scratch_pad_t sp; @@ -232,18 +254,15 @@ H5VL_iod_server_group_open_cb(AXE_engine_t UNUSED axe_engine, 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 */ -#if 0 - /* When we have a real IOD, open the scratch pad and read the - group's metadata */ - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_gcpl", NULL, - &output.gcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset gcpl lookup failed"); - if(NULL == (output.gcpl = H5MM_malloc (output.gcpl_size))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate gcpl buffer"); - if(iod_kv_get_value(mdkv_oh, IOD_TID_UNKNOWN, "dataset_gcpl", output.gcpl, - &output.gcpl_size, NULL, NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "dataset dcpl lookup failed"); + /* MSC - retrieve metadata, need IOD */ +#if 0 + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_PLIST, "create_plist", + NULL, NULL, NULL, &output.gcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve gcpl"); + + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_LINK_COUNT, "link_count", + NULL, NULL, NULL, &output.link_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count"); #endif /* close the metadata scratch pad */ diff --git a/src/H5VLiod_map.c b/src/H5VLiod_map.c new file mode 100644 index 0000000..002d315 --- /dev/null +++ b/src/H5VLiod_map.c @@ -0,0 +1,868 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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, attr_id; + char *last_comp; /* the name of the group obtained from traversal function */ + 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"); + + /* create the attribute KV object for the root group */ + if(iod_obj_create(coh, IOD_TID_UNKNOWN, NULL, IOD_OBJ_KV, + NULL, NULL, &attr_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 = attr_id; + 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"); + + /* Open Metadata KV object for write */ + 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"); + + /* insert link count metadata */ + if(H5VL_iod_insert_link_count(mdkv_oh, IOD_TID_UNKNOWN, (uint64_t)1, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* insert object type metadata */ + if(H5VL_iod_insert_object_type(mdkv_oh, IOD_TID_UNKNOWN, H5I_MAP, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + + /* MSC - insert Key datatype metadata */ + /* MSC - insert Value datatype metadata */ + + /* close MD KV object */ + if(iod_obj_close(mdkv_oh, NULL, NULL)) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't close object"); + + /* add link in parent group to current object */ + if(H5VL_iod_insert_new_link(cur_oh, IOD_TID_UNKNOWN, last_comp, map_id, + NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't insert KV value"); + } /* 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 - need IOD*/ +#if 0 + if(H5VL_iod_get_metadata(mdkv_oh, IOD_TID_UNKNOWN, H5VL_IOD_LINK_COUNT, "link_count", + NULL, NULL, NULL, &output.link_count) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "failed to retrieve link count"); +#endif + + /* 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_obj.c b/src/H5VLiod_obj.c index be0dfe0..ad64a75 100644 --- a/src/H5VLiod_obj.c +++ b/src/H5VLiod_obj.c @@ -85,7 +85,7 @@ H5VL_iod_server_object_open_cb(AXE_engine_t UNUSED axe_engine, if (iod_obj_open_write(coh, obj_id, NULL, &obj_oh, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't open current group"); - /* get scratch pad of the dataset */ + /* get scratch pad of the object */ 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"); @@ -540,7 +540,7 @@ H5VL_iod_server_object_get_comment_cb(AXE_engine_t UNUSED axe_engine, #if H5_DO_NATIVE if(0 != length) { size = H5Oget_comment(loc_oh.cookie, NULL, length); - comment.value = malloc(size); + comment.value = malloc(size+1); } if((size = H5Oget_comment(loc_oh.cookie, comment.value, length)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "Unable to get object comment"); diff --git a/src/H5VLiod_server.c b/src/H5VLiod_server.c index 8d34eaf..e82d507 100644 --- a/src/H5VLiod_server.c +++ b/src/H5VLiod_server.c @@ -110,6 +110,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, @@ -170,9 +187,7 @@ H5VLiod_start_handler(MPI_Comm comm, MPI_Info UNUSED info) /* Loop tp receive requests from clients */ while(1) { - /* Receive new function calls */ - if(HG_SUCCESS != HG_Handler_process(HG_HANDLER_MAX_IDLE_TIME, HG_STATUS_IGNORE)) - return FAIL; + HG_Handler_process(0, HG_STATUS_IGNORE); if(shutdown) break; } @@ -1702,6 +1717,18 @@ H5VL_iod_server_dset_close(hg_handle_t handle) i, input->parent_axe_ids.ids[i], status); } #endif +#if 0 + int i; + AXE_status_t status; + for(i=0 ; i<input->parent_axe_ids.count ; i++) { + if(AXEget_status(engine, input->parent_axe_ids.ids[i], &status) < 0) { + fprintf(stderr, "GET STATUS FAILED\n"); + exit(1); + } + fprintf(stderr, "%d: AXE ID %llu status %d\n", + i, input->parent_axe_ids.ids[i], status); + } +#endif if (AXE_SUCCEED != AXEcreate_task(engine, input->axe_id, input->parent_axe_ids.count, input->parent_axe_ids.ids, 0, NULL, @@ -2505,6 +2532,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, @@ -2641,9 +3109,11 @@ H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs) if(NULL != hslabs) { hsize_t *points = NULL; + size_t point_count = 0; + + point_count = ndims * num_descriptors * sizeof(hsize_t); - if(NULL == (points = (hsize_t *)malloc(sizeof(hsize_t) * ndims * - (hsize_t)num_descriptors))) + if(NULL == (points = (hsize_t *)malloc(point_count))) HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for points coords"); if(H5Sget_select_elem_pointlist(space_id, (hsize_t)0, @@ -2652,13 +3122,18 @@ H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs) /* populate the hyperslab */ for(n=0 ; n<num_descriptors ; n++) { + hsize_t *cur_ptr = points; /* temp pointer into points array */ + + /* adjust the current pointer to the current point */ + cur_ptr += n*ndims; for(i=0 ; i<ndims ; i++) { - hslabs[n].start[i] = *points++; + hslabs[n].start[i] = *(cur_ptr+i); hslabs[n].stride[i] = 1; - hslabs[n].block[i] = 1; hslabs[n].count[i] = 1; + hslabs[n].block[i] = *(cur_ptr+ndims+i) + 1 - hslabs[n].start[i]; } } + free(points); } break; @@ -2680,29 +3155,37 @@ H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "Failed to retrieve hyperslab selection"); } } - /* Otherwise populate the hslabs by gettinge very block */ + /* Otherwise populate the hslabs by getting every block */ else { if((num_descriptors = H5Sget_select_hyper_nblocks(space_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "invalid hyperslab selection"); if(NULL != hslabs) { - hsize_t *blocks; - fprintf (stderr, "num_descriptors from : %llu get file desc \n", num_descriptors); - if(NULL == (blocks = (hsize_t *)malloc(sizeof(hsize_t) * 2 * - ndims * num_descriptors))) + hsize_t *blocks = NULL; + size_t block_count = 0; + + block_count = ndims * num_descriptors * sizeof(hsize_t) * 2; + + if(NULL == (blocks = (hsize_t *)malloc(block_count))) HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate array for points coords"); + fprintf(stderr, "block count = %zu\n", block_count); + if(H5Sget_select_hyper_blocklist(space_id, (hsize_t)0, (hsize_t)num_descriptors, blocks) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "Failed to retrieve point coordinates"); /* populate the hyperslab */ for(n=0 ; n<num_descriptors ; n++) { + hsize_t *cur_ptr = blocks; /* temp pointer into blocks array */ + + /* adjust the current pointer to the current block */ + cur_ptr += n*ndims*2; for(i=0 ; i<ndims ; i++) { - hslabs[n].start[i] = *blocks++; + hslabs[n].start[i] = *(cur_ptr+i); hslabs[n].stride[i] = 1; - hslabs[n].block[i] = 1; - hslabs[n].count[i] = *blocks++; + hslabs[n].count[i] = 1; + hslabs[n].block[i] = *(cur_ptr+ndims+i) + 1 - hslabs[n].start[i]; } } @@ -2723,6 +3206,322 @@ done: FUNC_LEAVE_NOAPI(ret_value) } +herr_t +H5VL_iod_insert_plist(iod_handle_t oh, iod_trans_id_t tid, hid_t plist_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event) +{ + void *key = NULL; + void *value = NULL; + iod_kv_t kv; + size_t buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* insert group creation properties in Metadata KV */ + key = strdup("create_plist"); + + /* determine the buffer size needed to store the encoded plist */ + if(H5Pencode(plist_id, NULL, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode plist"); + if(NULL == (value = malloc (buf_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate plist buffer"); + /* encode plist */ + if(H5Pencode(plist_id, value, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode plist"); + + kv.key = (char *)key; + kv.value = value; + kv.value_len = (iod_size_t)buf_size; + /* insert kv pair into scratch pad */ + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(key) { + free(key); + key = NULL; + } + if(value) { + free(value); + value = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_insert_link_count(iod_handle_t oh, iod_trans_id_t tid, uint64_t count, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event) +{ + void *key = NULL; + void *value = NULL; + iod_kv_t kv; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + key = strdup("link_count"); + if(NULL == (value = malloc (sizeof(uint64_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + + *((uint64_t *)value) = count; + kv.key = (char *)key; + kv.value = value; + kv.value_len = sizeof(uint64_t); + + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(key) { + free(key); + key = NULL; + } + if(value) { + free(value); + value = NULL; + } + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_insert_object_type(iod_handle_t oh, iod_trans_id_t tid, H5I_type_t obj_type, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event) +{ + void *key = NULL; + void *value = NULL; + iod_kv_t kv; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + key = strdup("object_type"); + + if(NULL == (value = malloc (sizeof(int32_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + + *((int32_t *)value) = obj_type; + kv.key = (char *)key; + kv.value = value; + kv.value_len = sizeof(int32_t); + + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(key) { + free(key); + key = NULL; + } + if(value) { + free(value); + value = NULL; + } + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_insert_new_link(iod_handle_t oh, iod_trans_id_t tid, char *link_name, + iod_obj_id_t obj_id, iod_hint_list_t *hints, + iod_checksum_t *cs, iod_event_t *event) +{ + void *value = NULL; + iod_kv_t kv; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (value = malloc (sizeof(iod_obj_id_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate buffer"); + + *((int32_t *)value) = obj_id; + kv.key = link_name; + kv.value = value; + kv.value_len = sizeof(iod_obj_id_t); + + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(value) { + free(value); + value = NULL; + } + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_insert_datatype(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event) +{ + void *key = NULL; + void *value = NULL; + iod_kv_t kv; + size_t buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* insert group creation properties in Metadata KV */ + key = strdup("datatype"); + + /* determine the buffer size needed to store the encoded type */ + if(H5Tencode(type_id, NULL, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type"); + if(NULL == (value = malloc (buf_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate type buffer"); + /* encode type */ + if(H5Tencode(type_id, value, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode type"); + + kv.key = (char *)key; + kv.value = value; + kv.value_len = (iod_size_t)buf_size; + /* insert kv pair into scratch pad */ + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(key) { + free(key); + key = NULL; + } + if(value) { + free(value); + value = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_insert_dataspace(iod_handle_t oh, iod_trans_id_t tid, hid_t space_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event) +{ + void *key = NULL; + void *value = NULL; + iod_kv_t kv; + size_t buf_size; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* insert group creation properties in Metadata KV */ + key = strdup("dataspace"); + + /* determine the buffer size needed to store the encoded space */ + if(H5Sencode(space_id, NULL, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode space"); + if(NULL == (value = malloc (buf_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate space buffer"); + /* encode space */ + if(H5Sencode(space_id, value, &buf_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "failed to encode space"); + + kv.key = (char *)key; + kv.value = value; + kv.value_len = (iod_size_t)buf_size; + /* insert kv pair into scratch pad */ + if (iod_kv_set(oh, tid, hints, &kv, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); + +done: + if(key) { + free(key); + key = NULL; + } + if(value) { + free(value); + value = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) +} + +herr_t +H5VL_iod_get_metadata(iod_handle_t oh, iod_trans_id_t tid, H5VL_iod_metadata_t md_type, + const char *key, iod_hint_list_t *hints, iod_checksum_t *cs, + iod_event_t *event, void *ret) +{ + iod_size_t val_size = 0; + void *value; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + switch(md_type) { + case H5VL_IOD_PLIST: + { + hid_t plist_id = *((hid_t *)ret); + + if(iod_kv_get_value(oh, tid, key, NULL, &val_size, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if(NULL == (value = malloc (val_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer"); + + if(iod_kv_get_value(oh, tid, key, value, &val_size, hints, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if((plist_id = H5Pdecode(value)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode gcpl"); + break; + } + case H5VL_IOD_LINK_COUNT: + val_size = sizeof(uint64_t); + if(iod_kv_get_value(oh, tid, key, ret, &val_size, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "link_count lookup failed"); + break; + case H5VL_IOD_DATATYPE: + { + hid_t type_id = *((hid_t *)ret); + + if(iod_kv_get_value(oh, tid, key, NULL, &val_size, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if(NULL == (value = malloc (val_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer"); + + if(iod_kv_get_value(oh, tid, key, value, &val_size, hints, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if((type_id = H5Tdecode(value)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode gcpl"); + break; + } + case H5VL_IOD_DATASPACE: + { + hid_t space_id = *((hid_t *)ret); + + if(iod_kv_get_value(oh, tid, key, NULL, &val_size, cs, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if(NULL == (value = malloc (val_size))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate value buffer"); + + if(iod_kv_get_value(oh, tid, key, value, &val_size, hints, event) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "lookup failed"); + + if((space_id = H5Tdecode(value)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "failed to decode gcpl"); + break; + } + default: + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "invalide metadata type"); + } +done: + if(value) { + free(value); + value = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) +} + + + + #if 0 /*------------------------------------------------------------------------- diff --git a/src/H5VLiod_server.h b/src/H5VLiod_server.h index 4407665..666bbb8 100644 --- a/src/H5VLiod_server.h +++ b/src/H5VLiod_server.h @@ -32,6 +32,15 @@ #define H5_DO_NATIVE 0 #define DEBUG_COMPACTOR 1 +/* Enum for metadata types stored in MD KV for HDF5->IOD objects */ +typedef enum H5VL_iod_metadata_t { + H5VL_IOD_PLIST, /*type ID for property lists */ + H5VL_IOD_LINK_COUNT, /*type ID for link count */ + H5VL_IOD_OBJECT_TYPE, /*type ID for object type */ + H5VL_IOD_DATATYPE, /*type ID for datatypes */ + H5VL_IOD_DATASPACE /*type ID for dataspaces */ +} H5VL_iod_metadata_t; + /* the AXE op data strucutre stored with every operation */ typedef struct op_data_t { void *input; @@ -67,6 +76,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); @@ -164,6 +181,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[], @@ -205,9 +254,9 @@ H5_DLL void H5VL_iod_server_link_create_cb(AXE_engine_t axe_engine, size_t num_s_parents, AXE_task_t s_parents[], void *op_data); H5_DLL void H5VL_iod_server_link_move_cb(AXE_engine_t axe_engine, - size_t num_n_parents, AXE_task_t n_parents[], - size_t num_s_parents, AXE_task_t s_parents[], - void *op_data); + size_t num_n_parents, AXE_task_t n_parents[], + size_t num_s_parents, AXE_task_t s_parents[], + void *op_data); H5_DLL void H5VL_iod_server_link_exists_cb(AXE_engine_t axe_engine, size_t num_n_parents, AXE_task_t n_parents[], size_t num_s_parents, AXE_task_t s_parents[], @@ -238,10 +287,26 @@ H5_DLL void H5VL_iod_server_object_get_comment_cb(AXE_engine_t UNUSED axe_engine size_t num_s_parents, AXE_task_t s_parents[], void *_op_data); +/* Helper routines used several times in different places */ H5_DLL herr_t H5VL_iod_server_traverse(iod_handle_t coh, iod_obj_id_t loc_id, iod_handle_t loc_handle, const char *path, hbool_t create_interm_grps, char **last_comp, iod_obj_id_t *iod_id, iod_handle_t *iod_oh); H5_DLL herr_t H5VL_iod_get_file_desc(hid_t space_id, hssize_t *count, iod_hyperslab_t *hslabs); - +H5_DLL herr_t H5VL_iod_insert_plist(iod_handle_t oh, iod_trans_id_t tid, hid_t plist_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_insert_link_count(iod_handle_t oh, iod_trans_id_t tid, uint64_t count, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_insert_object_type(iod_handle_t oh, iod_trans_id_t tid, H5I_type_t obj_type, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_insert_datatype(iod_handle_t oh, iod_trans_id_t tid, hid_t type_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_insert_dataspace(iod_handle_t oh, iod_trans_id_t tid, hid_t space_id, + iod_hint_list_t *hints, iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_insert_new_link(iod_handle_t oh, iod_trans_id_t tid, char *link_name, + iod_obj_id_t obj_id, iod_hint_list_t *hints, + iod_checksum_t *cs, iod_event_t *event); +H5_DLL herr_t H5VL_iod_get_metadata(iod_handle_t oh, iod_trans_id_t tid, H5VL_iod_metadata_t md_type, + const char *key, iod_hint_list_t *hints, iod_checksum_t *cs, + iod_event_t *event, void *ret); #endif /* H5_HAVE_EFF */ #endif /* _H5VLiod_server_H */ 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 8fa8732..eabfa84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,11 +62,12 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5VL.c H5VLint.c H5VLnative.c \ H5VLiod.c H5VLiod_client.c H5VLiod_server.c \ H5VLiod_encdec.c H5VLiod_compactor.c H5VLiod_compactor_queue.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 \ @@ -122,7 +123,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 cf0ba9f..4242315 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -139,11 +139,11 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5VLiod_server.lo H5VLiod_encdec.lo H5VLiod_file.lo \ H5VLiod_compactor_queue.lo H5VLiod_compactor.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 \ @@ -571,11 +571,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 \ @@ -631,7 +632,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 \ @@ -918,6 +919,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@ @@ -1034,6 +1036,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@ |