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