diff options
Diffstat (limited to 'src/H5M.c')
-rw-r--r-- | src/H5M.c | 575 |
1 files changed, 575 insertions, 0 deletions
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() */ + |