summaryrefslogtreecommitdiffstats
path: root/src/H5VLdyn_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5VLdyn_ops.c')
-rw-r--r--src/H5VLdyn_ops.c334
1 files changed, 334 insertions, 0 deletions
diff --git a/src/H5VLdyn_ops.c b/src/H5VLdyn_ops.c
new file mode 100644
index 0000000..0992452
--- /dev/null
+++ b/src/H5VLdyn_ops.c
@@ -0,0 +1,334 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: The Virtual Object Layer as described in documentation.
+ * The pupose is to provide an abstraction on how to access the
+ * underlying HDF5 container, whether in a local file with
+ * a specific file format, or remotely on other machines, etc...
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5VLmodule.h" /* This source code file is part of the H5VL module */
+
+/***********/
+/* Headers */
+/***********/
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5SLprivate.h" /* Skip lists */
+#include "H5VLpkg.h" /* Virtual Object Layer */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Dynamic operation info */
+typedef struct H5VL_dyn_op_t {
+ char *op_name; /* Name of operation */
+ int op_val; /* Value of operation */
+} H5VL_dyn_op_t;
+
+/********************/
+/* Local Prototypes */
+/********************/
+static void H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* The current optional operation values */
+static int H5VL_opt_vals_g[H5VL_SUBCLS_TOKEN + 1] = {
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_NONE */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_INFO */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_WRAP */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_ATTR */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATASET */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATATYPE */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_FILE */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_GROUP */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_LINK */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_OBJECT */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_REQUEST */
+ H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_BLOB */
+ H5VL_RESERVED_NATIVE_OPTIONAL /* H5VL_SUBCLS_TOKEN */
+};
+
+/* The current optional operations' info */
+static H5SL_t *H5VL_opt_ops_g[H5VL_SUBCLS_TOKEN + 1] = {
+ NULL, /* H5VL_SUBCLS_NONE */
+ NULL, /* H5VL_SUBCLS_INFO */
+ NULL, /* H5VL_SUBCLS_WRAP */
+ NULL, /* H5VL_SUBCLS_ATTR */
+ NULL, /* H5VL_SUBCLS_DATASET */
+ NULL, /* H5VL_SUBCLS_DATATYPE */
+ NULL, /* H5VL_SUBCLS_FILE */
+ NULL, /* H5VL_SUBCLS_GROUP */
+ NULL, /* H5VL_SUBCLS_LINK */
+ NULL, /* H5VL_SUBCLS_OBJECT */
+ NULL, /* H5VL_SUBCLS_REQUEST */
+ NULL, /* H5VL_SUBCLS_BLOB */
+ NULL /* H5VL_SUBCLS_TOKEN */
+};
+
+/* Declare a free list to manage the H5VL_class_t struct */
+H5FL_DEFINE_STATIC(H5VL_dyn_op_t);
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__release_dyn_op
+ *
+ * Purpose: Release a dynamic operation info node
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+static void
+H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ H5MM_xfree(dyn_op->op_name);
+ H5FL_FREE(H5VL_dyn_op_t, dyn_op);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* H5VL__release_dyn_op() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__term_opt_operation_cb
+ *
+ * Purpose: Callback for releasing a dynamically registered operation info
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__term_opt_operation_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data)
+{
+ H5VL_dyn_op_t *item = (H5VL_dyn_op_t *)_item; /* Item to release */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Release the dynamically registered operation info */
+ H5VL__release_dyn_op(item);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5VL__term_opt_operation_cb() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__term_opt_operation
+ *
+ * Purpose: Terminate the dynamically registered optional operations,
+ * releasing all operations.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL__term_opt_operation(void)
+{
+ size_t subcls; /* Index over the elements of operation array */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Iterate over the VOL subclasses */
+ for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++)
+ if (H5VL_opt_ops_g[subcls])
+ H5SL_destroy(H5VL_opt_ops_g[subcls], H5VL__term_opt_operation_cb, NULL);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5VL__term_opt_operation() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__register_opt_operation
+ *
+ * Purpose: Register a new optional operation for a VOL object subclass.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val)
+{
+ H5VL_dyn_op_t *new_op; /* Info about new operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(op_val);
+ HDassert(op_name && *op_name);
+
+ /* Check for duplicate operation */
+ if (H5VL_opt_ops_g[subcls]) {
+ if (NULL != H5SL_search(H5VL_opt_ops_g[subcls], op_name))
+ HGOTO_ERROR(H5E_VOL, H5E_EXISTS, FAIL, "operation name already exists")
+ } /* end if */
+ else {
+ /* Create skip list for operation of this subclass */
+ if (NULL == (H5VL_opt_ops_g[subcls] = H5SL_create(H5SL_TYPE_STR, NULL)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create skip list for operations")
+ } /* end else */
+
+ /* Register new operation */
+ if (NULL == (new_op = H5FL_CALLOC(H5VL_dyn_op_t)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate memory for dynamic operation info")
+ if (NULL == (new_op->op_name = H5MM_strdup(op_name)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate name for dynamic operation info")
+ new_op->op_val = H5VL_opt_vals_g[subcls]++;
+
+ /* Insert into subclass's skip list */
+ if (H5SL_insert(H5VL_opt_ops_g[subcls], new_op, new_op->op_name) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert operation info into skip list")
+
+ /* Return the next operation value to the caller */
+ *op_val = new_op->op_val;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__register_opt_operation() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__num_opt_operation
+ *
+ * Purpose: Returns the # of currently registered optional operations
+ *
+ * Return: # of registered optional operations / <can't fail>
+ *
+ *---------------------------------------------------------------------------
+ */
+size_t
+H5VL__num_opt_operation(void)
+{
+ size_t subcls; /* Index over the elements of operation array */
+ size_t ret_value = 0; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Iterate over the VOL subclasses */
+ for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++)
+ if (H5VL_opt_ops_g[subcls])
+ ret_value += H5SL_count(H5VL_opt_ops_g[subcls]);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__num_opt_operation() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__find_opt_operation
+ *
+ * Purpose: Look up a optional operation for a VOL object subclass, by name.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(op_val);
+ HDassert(op_name && *op_name);
+
+ /* Check for dynamic operations in the VOL subclass */
+ if (H5VL_opt_ops_g[subcls]) {
+ H5VL_dyn_op_t *dyn_op; /* Info about operation */
+
+ /* Search for dynamic operation with correct name */
+ if (NULL == (dyn_op = H5SL_search(H5VL_opt_ops_g[subcls], op_name)))
+ HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered")
+
+ /* Set operation value for user */
+ *op_val = dyn_op->op_val;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__find_opt_operation() */
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL__unregister_opt_operation
+ *
+ * Purpose: Unregister a optional operation for a VOL object subclass, by name.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(op_name && *op_name);
+
+ /* Check for dynamic operations in the VOL subclass */
+ if (H5VL_opt_ops_g[subcls]) {
+ H5VL_dyn_op_t *dyn_op; /* Info about operation */
+
+ /* Search for dynamic operation with correct name */
+ if (NULL == (dyn_op = H5SL_remove(H5VL_opt_ops_g[subcls], op_name)))
+ HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered")
+
+ /* Release the info for the operation */
+ H5VL__release_dyn_op(dyn_op);
+
+ /* Close the skip list, if no more operations in it */
+ if (0 == H5SL_count(H5VL_opt_ops_g[subcls])) {
+ if (H5SL_close(H5VL_opt_ops_g[subcls]) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "can't close dyn op skip list")
+ H5VL_opt_ops_g[subcls] = NULL;
+ } /* end if */
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5VL__unregister_opt_operation() */