summaryrefslogtreecommitdiffstats
path: root/src/H5M.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5M.c')
-rw-r--r--src/H5M.c575
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() */
+