summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJerome Soumagne <jsoumagne@hdfgroup.org>2016-04-27 20:33:32 (GMT)
committerJerome Soumagne <jsoumagne@hdfgroup.org>2016-11-29 23:42:32 (GMT)
commit15a79009266ab9f05deeac6131752fb91568501c (patch)
tree09ffe4dd68fe6d6335e96a6f2feaf9926f781fbd /src
parent57da98f0fbf4177c29b735d7f91900aa063557cc (diff)
downloadhdf5-15a79009266ab9f05deeac6131752fb91568501c.zip
hdf5-15a79009266ab9f05deeac6131752fb91568501c.tar.gz
hdf5-15a79009266ab9f05deeac6131752fb91568501c.tar.bz2
Add support for metadata query in H5Q
Refactor code between data/metadata query Store metadata plugin info in superblock Add dummy metadata plugin Tweak query and index tests
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5Dint.c17
-rw-r--r--src/H5Dprivate.h9
-rw-r--r--src/H5Fint.c274
-rw-r--r--src/H5Fpkg.h4
-rw-r--r--src/H5Fprivate.h17
-rw-r--r--src/H5Fsuper.c15
-rw-r--r--src/H5Q.c222
-rw-r--r--src/H5X.c267
-rw-r--r--src/H5Xmeta_dummy.c1439
-rw-r--r--src/H5Xpkg.h5
-rw-r--r--src/H5Xprivate.h10
-rw-r--r--src/H5Xpublic.h18
14 files changed, 2200 insertions, 100 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 388ff28..4bf412c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -634,6 +634,7 @@ IDE_GENERATED_PROPERTIES ("H5WB" "${H5WB_HDRS}" "${H5WB_SRCS}" )
set (H5X_SRCS
${HDF5_SRC_DIR}/H5X.c
${HDF5_SRC_DIR}/H5Xdummy.c
+ ${HDF5_SRC_DIR}/H5Xmeta_dummy.c
${HDF5_SRC_DIR}/H5Pxapl.c
${HDF5_SRC_DIR}/H5Pxcpl.c
${HDF5_SRC_DIR}/H5Pxxpl.c
diff --git a/src/H5D.c b/src/H5D.c
index 715358a..5ff1e03 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -154,7 +154,7 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
dset->shared->dset_id = ret_value;
/* Create index if told to */
- if(H5X_can_create(ret_value, dcpl_id) < 0)
+ if(H5X_can_create_data(ret_value, dcpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "Index can't be created on this dataset")
done:
diff --git a/src/H5Dint.c b/src/H5Dint.c
index f84bdb7..7981ceb 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -3161,16 +3161,14 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_set_index(H5D_t *dset, unsigned count, H5X_class_t **idx_class,
- void **idx_handle, H5O_idxinfo_t *idx_info)
+H5D_set_index(H5D_t *dset, H5X_class_t *idx_class, void *idx_handle,
+ H5O_idxinfo_t *idx_info)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(dset);
- /* Do not support more than one index for now */
- HDassert(count <= 1);
HDassert(idx_class);
HDassert(idx_handle);
HDassert(idx_info);
@@ -3180,8 +3178,8 @@ H5D_set_index(H5D_t *dset, unsigned count, H5X_class_t **idx_class,
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update index header message");
/* Set user data for index */
- dset->shared->idx_class = *idx_class;
- dset->shared->idx_handle = *idx_handle;
+ dset->shared->idx_class = idx_class;
+ dset->shared->idx_handle = idx_handle;
if (NULL == H5O_msg_copy(H5O_IDXINFO_ID, idx_info, &dset->shared->idx_info))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to update copy message");
@@ -3200,22 +3198,19 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_get_index(H5D_t *dset, unsigned max_count, H5X_class_t **idx_class,
- void **idx_handle, H5O_idxinfo_t **idx_info, unsigned *actual_count)
+H5D_get_index(H5D_t *dset, H5X_class_t **idx_class, void **idx_handle,
+ H5O_idxinfo_t **idx_info)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(dset);
- HDassert(max_count);
/* Get user data for index */
if (idx_class) *idx_class = dset->shared->idx_class;
if (idx_handle) *idx_handle = dset->shared->idx_handle;
if (idx_info) *idx_info = &dset->shared->idx_info;
- /* Just one index for now */
- if (actual_count) *actual_count = (dset->shared->idx_class) ? 1 : 0;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_get_index() */
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 121da08..34fa1fb 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -178,11 +178,10 @@ H5_DLL hid_t H5D_get_create_plist(H5D_t *dset);
H5_DLL hid_t H5D_get_access_plist(H5D_t *dset);
H5_DLL hid_t H5D_get_space(H5D_t *dset);
H5_DLL hid_t H5D_get_type(H5D_t *dset);
-H5_DLL herr_t H5D_set_index(H5D_t *dset, unsigned count, H5X_class_t **idx_class,
- void **idx_handle, H5O_idxinfo_t *idx_info);
-H5_DLL herr_t H5D_get_index(H5D_t *dset, unsigned max_count,
- H5X_class_t **idx_class, void **idx_handle, H5O_idxinfo_t **idx_info,
- unsigned *actual_count);
+H5_DLL herr_t H5D_set_index(H5D_t *dset, H5X_class_t *idx_class,
+ void *idx_handle, H5O_idxinfo_t *idx_info);
+H5_DLL herr_t H5D_get_index(H5D_t *dset, H5X_class_t **idx_class,
+ void **idx_handle, H5O_idxinfo_t **idx_info);
H5_DLL herr_t H5D_remove_index(H5D_t *dset, unsigned plugin_id);
H5_DLL herr_t H5D_get_index_size(H5D_t *dset, hsize_t *idx_size);
H5_DLL H5S_t *H5D_query(H5D_t *dset, const H5S_t *file_space, const H5Q_t *query,
diff --git a/src/H5Fint.c b/src/H5Fint.c
index a5621b3..d07c26e 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -77,6 +77,8 @@ static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl,
const char *name, char ** /*out*/ actual_name);/* Declare a free list to manage the H5F_t struct */
+static herr_t H5F_open_index(H5F_t *file, hid_t xapl_id);
+static herr_t H5F_close_index(H5F_t *file);
/*********************/
/* Package Variables */
@@ -786,7 +788,12 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush)
HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock")
f->shared->sblock = NULL;
} /* end if */
-
+
+ /* Release index info */
+ if (FAIL == H5O_msg_reset(H5O_IDXINFO_ID, &f->shared->idx_info))
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
+
/* Remove shared file struct from list of open files */
if(H5F_sfile_remove(f->shared) < 0)
/* Push error, but keep going*/
@@ -1215,6 +1222,10 @@ H5F_close(H5F_t *f)
HDassert(f);
HDassert(f->file_id > 0); /* This routine should only be called when a file ID's ref count drops to zero */
+ /* Close index object if index is closed */
+ if (f->shared->idx_handle && (FAIL == H5F_close_index(f)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "cannot close index")
+
/* Perform checks for "semi" file close degree here, since closing the
* file is not allowed if there are objects still open */
if(f->shared->fc_degree == H5F_CLOSE_SEMI) {
@@ -2090,3 +2101,264 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__set_eoa() */
+/*-------------------------------------------------------------------------
+ * Function: H5F_set_index
+ *
+ * Purpose: Set index information.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_set_index(H5F_t *file, H5X_class_t *idx_class, void *idx_handle,
+ struct H5O_idxinfo_t *idx_info)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+ HDassert(idx_class);
+ HDassert(idx_handle);
+ HDassert(idx_info);
+
+ /* Write the index header message */
+ if(H5F_super_ext_write_msg(file, H5AC_dxpl_id, idx_info, H5O_IDXINFO_ID, TRUE) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
+
+ /* Set user data for index */
+ file->shared->idx_class = idx_class;
+ file->shared->idx_handle = idx_handle;
+ if (NULL == H5O_msg_copy(H5O_IDXINFO_ID, idx_info, &file->shared->idx_info))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to update copy message");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_set_index() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_index
+ *
+ * Purpose: Get index information.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_index(H5F_t *file, H5X_class_t **idx_class, void **idx_handle,
+ struct H5O_idxinfo_t **idx_info)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(file);
+
+ /* Get user data for index */
+ if (idx_class) *idx_class = file->shared->idx_class;
+ if (idx_handle) *idx_handle = file->shared->idx_handle;
+ if (idx_info) *idx_info = &file->shared->idx_info;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_index() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_open_index
+ *
+ * Purpose: Open index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_open_index(H5F_t *file, hid_t xapl_id)
+{
+ hid_t file_id;
+ H5X_class_t *idx_class;
+ void *idx_handle = NULL;
+ size_t metadata_size;
+ void *metadata;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+
+ file_id = file->file_id;
+ idx_class = file->shared->idx_class;
+ metadata_size = file->shared->idx_info.metadata_size;
+ metadata = file->shared->idx_info.metadata;
+
+ if (NULL == H5I_object_verify(file_id, H5I_FILE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
+ if (NULL == metadata)
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "no index metadata was found");
+ if (NULL == idx_class->idx_class.metadata_class.open)
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin open callback not defined");
+ if (NULL == (idx_handle = idx_class->idx_class.metadata_class.open(file_id, xapl_id, metadata_size, metadata)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTOPENOBJ, FAIL, "cannot open index");
+
+ file->shared->idx_handle = idx_handle;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_open_index() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_close_index
+ *
+ * Purpose: Close index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_close_index(H5F_t *file)
+{
+ H5X_class_t *idx_class;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+
+ idx_class = file->shared->idx_class;
+ if (NULL == (idx_class->idx_class.metadata_class.close))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin close callback not defined");
+ if (FAIL == idx_class->idx_class.metadata_class.close(file->shared->idx_handle))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "cannot close index");
+
+ file->shared->idx_handle = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_close_index() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_remove_index
+ *
+ * Purpose: Remove index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_remove_index(H5F_t *file, unsigned H5_ATTR_UNUSED plugin_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+
+ /* First close index if opened */
+ if (file->shared->idx_handle && (FAIL == H5F_close_index(file)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "cannot close index");
+
+ /* Remove idx_handle from file */
+ if(H5F_super_ext_remove_msg(file, H5AC_dxpl_id, H5O_IDXINFO_ID) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension")
+
+ if (FAIL == H5O_msg_reset(H5O_IDXINFO_ID, &file->shared->idx_info))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to free index index");
+
+ file->shared->idx_class = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_remove_index() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_index_size
+ *
+ * Purpose: Get index index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_index_size(H5F_t *file, hsize_t *idx_size)
+{
+ H5X_class_t *idx_class = NULL;
+ hsize_t actual_size = 0;
+ hid_t xapl_id = H5P_INDEX_ACCESS_DEFAULT; /* TODO for now */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+ HDassert(idx_size);
+
+ idx_class = file->shared->idx_class;
+ if (!idx_class)
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "index class not defined");
+ if (NULL == (idx_class->idx_class.metadata_class.get_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin get size callback not defined");
+ if (!file->shared->idx_handle && (FAIL == H5F_open_index(file, xapl_id)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTOPENOBJ, FAIL, "cannot open index");
+ if (FAIL == idx_class->idx_class.metadata_class.get_size(file->shared->idx_handle, &actual_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "cannot get index size");
+
+ *idx_size = actual_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_get_index_size() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_query
+ *
+ * Purpose: Returns a set of object/attribute references that match
+ * the query.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_query(H5F_t *file, const struct H5Q_t *query,
+ size_t *ref_count, href_t *refs[], hid_t xapl_id, hid_t xxpl_id)
+{
+ H5X_class_t *idx_class;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+ HDassert(query);
+ HDassert(ref_count);
+ HDassert(refs);
+
+ idx_class = file->shared->idx_class;
+
+ if (!idx_class)
+ HGOTO_DONE(SUCCEED);
+
+ /* Index associated to file so use it */
+ if (NULL == idx_class->idx_class.metadata_class.query)
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin query callback not defined");
+
+ /* Open index if not opened yet */
+ if (!file->shared->idx_handle && (FAIL == H5F_open_index(file, xapl_id)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTOPENOBJ, FAIL, "cannot open index");
+
+ /* Call query of index plugin */
+ if (FAIL == idx_class->idx_class.metadata_class.query(
+ file->shared->idx_handle, query->query_id, xxpl_id, ref_count, refs))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, FAIL, "cannot query index");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_query */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 2255085..3e2d19b 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -293,6 +293,10 @@ struct H5F_file_t {
/* Metadata accumulator information */
H5F_meta_accum_t accum; /* Metadata accumulator info */
+
+ void *idx_handle; /* Handle for the index */
+ H5X_class_t *idx_class; /* Class for the index */
+ struct H5O_idxinfo_t idx_info; /* Index information */
};
/*
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 658d123..cbe30fe 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -24,10 +24,11 @@
#include "H5Fpublic.h"
/* Public headers needed by this file */
-#include "H5FDpublic.h" /* File drivers */
+#include "H5FDpublic.h" /* File drivers */
/* Private headers needed by this file */
-#include "H5VMprivate.h" /* Vectors and arrays */
+#include "H5VMprivate.h" /* Vectors and arrays */
+#include "H5Xprivate.h" /* Index */
/**************************/
@@ -555,6 +556,8 @@ struct H5UC_t;
struct H5O_loc_t;
struct H5HG_heap_t;
struct H5P_genplist_t;
+struct H5O_idxinfo_t;
+struct H5Q_t;
/* Forward declarations for anonymous H5F objects */
@@ -698,5 +701,15 @@ H5_DLL herr_t H5F_cwfs_remove_heap(H5F_file_t *shared, struct H5HG_heap_t *heap)
/* Debugging functions */
H5_DLL herr_t H5F_debug(H5F_t *f, FILE * stream, int indent, int fwidth);
+/* Index functions */
+H5_DLL herr_t H5F_set_index(H5F_t *f, H5X_class_t *idx_class,
+ void *idx_handle, struct H5O_idxinfo_t *idx_info);
+H5_DLL herr_t H5F_get_index(H5F_t *f, H5X_class_t **idx_class,
+ void **idx_handle, struct H5O_idxinfo_t **idx_info);
+H5_DLL herr_t H5F_remove_index(H5F_t *f, unsigned plugin_id);
+H5_DLL herr_t H5F_get_index_size(H5F_t *f, hsize_t *idx_size);
+H5_DLL herr_t H5F_query(H5F_t *file, const struct H5Q_t *query,
+ size_t *ref_count, href_t *refs[], hid_t xapl_id, hid_t xxpl_id);
+
#endif /* _H5Fprivate_H */
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index c6b1c83..e9f5797 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -574,6 +574,21 @@ H5F__super_read(H5F_t *f, hid_t dxpl_id)
f->shared->fs_addr[u] = fsinfo.fs_addr[u-1];
} /* end if */
+ /* Check for the extension having a 'index info' message */
+ if((status = H5O_msg_exists(&ext_loc, H5O_IDXINFO_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_EXISTS, FAIL, "can't check if message exists");
+ if(status) {
+ H5O_idxinfo_t *idx_info; /* Pointer to dataset's info info */
+ H5X_class_t *idx_class = NULL;
+
+ idx_info = &f->shared->idx_info;
+ if(NULL == H5O_msg_read(&ext_loc, H5O_IDXINFO_ID, idx_info, dxpl_id))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve message");
+ if (NULL == (idx_class = H5X_registered(idx_info->plugin_id)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get index plugin class");
+ f->shared->idx_class = idx_class;
+ } /* end if */
+
/* Close superblock extension */
if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension")
diff --git a/src/H5Q.c b/src/H5Q.c
index d6331be..49079a8 100644
--- a/src/H5Q.c
+++ b/src/H5Q.c
@@ -180,6 +180,25 @@ struct { \
} while (0)
#endif
+#define H5R_FRIEND
+#include "H5Rpkg.h" /* (Tmp) To re-use H5R__get_obj_name */
+
+#define H5X_DUMMY_MAX_NAME_LEN (64 * 1024)
+static void
+printf_ref(href_t ref)
+{
+ char obj_name[H5X_DUMMY_MAX_NAME_LEN];
+
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, ref, obj_name, H5X_DUMMY_MAX_NAME_LEN);
+ if (H5Rget_type(ref) == H5R_EXT_ATTR) {
+ char attr_name[H5X_DUMMY_MAX_NAME_LEN];
+ H5R__get_attr_name(NULL, ref, attr_name, H5X_DUMMY_MAX_NAME_LEN);
+ H5Q_LOG_DEBUG("Attribute reference: %s, %s", obj_name, attr_name);
+ } else {
+ H5Q_LOG_DEBUG("Object reference: %s", obj_name);
+ }
+}
+
/******************/
/* Local Typedefs */
/******************/
@@ -240,6 +259,8 @@ static herr_t H5Q__apply_attr_name(const H5Q_t *query, hbool_t *result,
static herr_t H5Q__apply_link_name(const H5Q_t *query, hbool_t *result,
const char *name);
+static herr_t H5Q__apply_index(hid_t loc_id, const H5Q_t *query,
+ H5Q_view_t *view, unsigned *result);
static herr_t H5Q__apply_iterate(hid_t oid, const char *name,
const H5O_info_t *oinfo, void *udata);
static herr_t H5Q__apply_object(hid_t oid, const char *name,
@@ -1880,15 +1901,16 @@ H5G_t *
H5Q_apply(hid_t loc_id, const H5Q_t *query, unsigned *result,
hid_t H5_ATTR_UNUSED vcpl_id)
{
- H5Q_apply_arg_t args;
H5Q_view_t view = H5Q_VIEW_INITIALIZER(view); /* Resulting view */
H5G_t *ret_grp = NULL; /* New group created */
- H5G_t *ret_value = NULL; /* Return value */
H5P_genclass_t *pclass = NULL;
unsigned flags;
- hid_t fapl_id = FAIL;
- H5F_t *new_file = NULL;
+ hid_t file_id = FAIL, fapl_id = FAIL;
+ H5F_t *file = NULL, *new_file = NULL;
H5G_loc_t file_loc;
+ H5X_class_t *idx_class = NULL;
+ H5Q_type_t query_type;
+ H5G_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1898,14 +1920,32 @@ H5Q_apply(hid_t loc_id, const H5Q_t *query, unsigned *result,
/* First check and optimize query */
/* TODO */
- /* Create new view and init args */
- args.query = query;
- args.result = result;
- args.view = &view;
+ if (FAIL == (file_id = H5I_get_file_id(loc_id, FALSE)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get file ID from location");
+ if (NULL == (file = H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a file");
+ if (FAIL == H5F_get_index(file, &idx_class, NULL, NULL))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get file index");
+ if (FAIL == H5Q_get_type(query, &query_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, NULL, "unable to get query type");
+
+ /* Use metadata index if available instead of visiting all objects */
+ /* TODO for now only use index if query is combined with metadata queries */
+ if (idx_class && (query_type != H5Q_TYPE_DATA_ELEM)) {
+ if (FAIL == H5Q__apply_index(loc_id, query, &view, result))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, NULL, "unable to use metadata index");
+ } else {
+ H5Q_apply_arg_t args;
- if (FAIL == H5O_visit(loc_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, H5Q__apply_iterate,
- &args, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADITER, NULL, "object visitation failed");
+ /* Create new view and init args */
+ args.query = query;
+ args.result = result;
+ args.view = &view;
+
+ if (FAIL == H5O_visit(loc_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE, H5Q__apply_iterate,
+ &args, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, NULL, "object visitation failed");
+ }
if (!H5Q_QUEUE_EMPTY(&view.reg_refs))
H5Q_LOG_DEBUG("Number of reg refs: %zu\n", view.reg_refs.n_elem);
@@ -1979,6 +2019,166 @@ done:
} /* end H5Q_apply() */
/*-------------------------------------------------------------------------
+ * Function: H5Q__apply_index
+ *
+ * Purpose: Private function for H5Q_apply.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q__apply_index(hid_t loc_id, const H5Q_t *query, H5Q_view_t *view,
+ unsigned *result)
+{
+ H5F_t *file = NULL;
+ hid_t xapl_id = H5P_INDEX_ACCESS_DEFAULT;
+ hid_t xxpl_id = H5P_INDEX_XFER_DEFAULT;
+ H5Q_type_t query_type;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (NULL == (file = H5I_object_verify(loc_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "loc_id is restricted to dataset");
+
+ if (FAIL == H5Q_get_type(query, &query_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+
+ /* TODO for now until we have wildcard support */
+ if (query_type == H5Q_TYPE_DATA_ELEM)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unsupported query type");
+
+ /* Query is only of the same metadata type (may be combined) */
+ if (query_type != H5Q_TYPE_MISC) {
+ size_t ref_count, i;
+ href_t *refs;
+
+ if (FAIL == H5F_query(file, query, &ref_count, &refs, xapl_id, xxpl_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, FAIL, "cannot query index");
+ for (i = 0; i < ref_count; i++) {
+ H5R_type_t ref_type = H5R_get_type(refs[i]);
+
+ // printf_ref(idx_refs[i]);
+ *result |= (ref_type == H5R_EXT_ATTR) ? H5Q_REF_ATTR : H5Q_REF_OBJ;
+ if (FAIL == H5Q__view_append(view, ref_type, refs[i]))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+ }
+ H5MM_free(refs);
+ } else {
+ /* Query is combined */
+ H5Q_combine_op_t op_type;
+
+ if (FAIL == H5Q_get_combine_op(query, &op_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get combine op");
+ if (op_type == H5Q_COMBINE_AND) {
+ H5Q_t *query1, *query2;
+ H5Q_type_t query1_type, query2_type;
+ const H5Q_t *data_query, *metadata_query;
+ size_t ref_count, i;
+ href_t *refs;
+
+ query1 = query->query.combine.l_query;
+ query2 = query->query.combine.r_query;
+
+ if (FAIL == H5Q_get_type(query1, &query1_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+ if (FAIL == H5Q_get_type(query2, &query2_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+
+ /* TODO clean that up */
+ if (query1_type == H5Q_TYPE_DATA_ELEM) {
+ data_query = query1;
+ metadata_query = query2;
+ } else if (query2_type == H5Q_TYPE_DATA_ELEM) {
+ data_query = query2;
+ metadata_query = query1;
+ } else {
+ data_query = NULL;
+ metadata_query = query;
+ }
+
+ /* Passing complex queries to plugins would be inefficient so we need to
+ * break queries down so that we only pass "AND combined" queries. This
+ * allows us to use a metadata index plugin on the metadata query part and
+ * a data index plugin on the data query part.
+ */
+ if (FAIL == H5F_query(file, metadata_query, &ref_count, &refs, xapl_id, xxpl_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, FAIL, "cannot query index");
+ for (i = 0; i < ref_count; i++) {
+ if (data_query) {
+ href_t ref;
+ hid_t obj_id = FAIL;
+ H5S_t *dataspace = NULL;
+ H5D_t *dataset = NULL;
+ char obj_name[64];
+
+// H5I_type_t obj_type;
+// if(H5R__get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref, obj_type) < 0)
+// HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object type")
+ if((obj_id = H5R__get_object(file, H5P_DATASET_ACCESS_DEFAULT, H5AC_ind_dxpl_id, refs[i], FALSE)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to get_object object")
+
+ H5R__get_obj_name(file, H5P_DEFAULT, H5P_DEFAULT, refs[i], obj_name, 64);
+
+ if (NULL == (dataset = (H5D_t *) H5I_object_verify(obj_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+
+ /* Query dataset */
+ if (NULL == (dataspace = H5D_query(dataset, NULL, data_query, H5P_INDEX_ACCESS_DEFAULT, H5P_INDEX_XFER_DEFAULT)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't query dataset");
+
+ /* No element matched the query */
+ if (H5S_SEL_NONE == H5S_get_select_type(dataspace))
+ HGOTO_DONE(SUCCEED);
+
+ *result = H5Q_REF_REG;
+
+ /* Keep dataset region reference */
+ if (NULL == (ref = H5R_create_ext_region(H5F_OPEN_NAME(file), obj_name, dataspace)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for region reference");
+ if (FAIL == H5Q__view_append(view, H5R_EXT_REGION, ref))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append region reference to view");
+
+ if (dataspace) H5S_close(dataspace);
+ if ((obj_id != FAIL) && (FAIL == H5I_dec_app_ref(obj_id)))
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
+ H5Rdestroy(refs[i]);
+ } else {
+ H5R_type_t ref_type = H5R_get_type(refs[i]);
+ // printf_ref(idx_refs[i]);
+ *result |= (ref_type == H5R_EXT_ATTR) ? H5Q_REF_ATTR : H5Q_REF_OBJ;
+ if (FAIL == H5Q__view_append(view, ref_type, refs[i]))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+ }
+ }
+ H5MM_free(refs);
+
+
+ /* Get data part of query */
+ } else {
+ H5Q_view_t view1 = H5Q_VIEW_INITIALIZER(view1), view2 = H5Q_VIEW_INITIALIZER(view2);
+ unsigned result1 = 0, result2 = 0;
+
+ if (FAIL == H5Q__apply_index(loc_id, query->query.combine.l_query, &view1, &result1))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query");
+ if (FAIL == H5Q__apply_index(loc_id, query->query.combine.r_query, &view2, &result2))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query");
+
+ if (FAIL == H5Q__view_combine(op_type, &view1, &view2, result1, result2,
+ view, result))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTMERGE, FAIL, "unable to merge results");
+
+ if (result1) H5Q__view_free(&view1);
+ if (result2) H5Q__view_free(&view2);
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5Q__apply_index() */
+
+/*-------------------------------------------------------------------------
* Function: H5Q__apply_iterate
*
* Purpose: Private function for H5Q_apply.
diff --git a/src/H5X.c b/src/H5X.c
index f35e22f..18ec4cf 100644
--- a/src/H5X.c
+++ b/src/H5X.c
@@ -46,6 +46,11 @@
/* Local Prototypes */
/********************/
+static herr_t H5X_create_data(hid_t loc_id, H5X_class_t *idx_class,
+ hid_t xcpl_id, hid_t xapl_id);
+static herr_t H5X_create_metadata(hid_t loc_id, H5X_class_t *idx_class,
+ hid_t xcpl_id, hid_t xapl_id);
+
/*********************/
/* Package Variables */
/*********************/
@@ -134,6 +139,8 @@ H5X__init_package(void)
if (H5X_register(H5X_FASTBIT) < 0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register FastBit index plugin");
#endif
+ if (H5X_register(H5X_META_DUMMY) < 0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register meta dummy index plugin");
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -380,7 +387,7 @@ done:
} /* end H5X_unregister() */
/*-------------------------------------------------------------------------
- * Function: H5X_can_create
+ * Function: H5X_can_create_data
*
* Purpose:
*
@@ -389,7 +396,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5X_can_create(hid_t dset_id, hid_t dcpl_id)
+H5X_can_create_data(hid_t dset_id, hid_t dcpl_id)
{
hid_t xcpl_id = H5P_DEFAULT;
herr_t ret_value = SUCCEED; /* Return value */
@@ -439,9 +446,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Xcreate(hid_t scope_id, unsigned plugin_id, hid_t xcpl_id)
+H5Xcreate(hid_t loc_id, unsigned plugin_id, hid_t xcpl_id)
{
- H5D_t *dset = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -450,10 +456,10 @@ H5Xcreate(hid_t scope_id, unsigned plugin_id, hid_t xcpl_id)
/* Check args */
if (plugin_id > H5X_PLUGIN_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid plugin identification number");
- if (NULL == (dset = (H5D_t *) H5I_object_verify(scope_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ if (FAIL == loc_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid loc ID");
- if (FAIL == H5X_create(scope_id, plugin_id, xcpl_id))
+ if (FAIL == H5X_create(loc_id, plugin_id, xcpl_id))
HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "cannot create index");
done:
@@ -470,21 +476,16 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5X_create(hid_t dset_id, unsigned plugin_id, hid_t xcpl_id)
+H5X_create(hid_t loc_id, unsigned plugin_id, hid_t xcpl_id)
{
H5X_class_t *idx_class = NULL;
- void *idx_handle = NULL; /* pointer to index object created */
- H5D_t *dset = NULL;
hid_t xapl_id = H5P_INDEX_ACCESS_DEFAULT; /* TODO for now */
- size_t metadata_size; /* size of metadata created by plugin */
- void *metadata; /* metadata created by plugin that needs to be stored */
- H5O_idxinfo_t idx_info;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check args */
- HDassert(dset_id != FAIL);
+ HDassert(loc_id != FAIL);
HDassert(plugin_id <= H5X_PLUGIN_MAX);
/* Is the plugin already registered */
@@ -498,27 +499,114 @@ H5X_create(hid_t dset_id, unsigned plugin_id, hid_t xcpl_id)
if (TRUE != H5P_isa_class(xcpl_id, H5P_INDEX_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not index creation property list");
+ if (idx_class->type == H5X_TYPE_DATA) {
+ if (FAIL == H5X_create_data(loc_id, idx_class, xcpl_id, xapl_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "cannot create data index");
+ }
+ else if (idx_class->type == H5X_TYPE_METADATA) {
+ if (FAIL == H5X_create_metadata(loc_id, idx_class, xcpl_id, xapl_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "cannot create metadata index");
+ } else
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "invalid index type");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_create() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_create_data
+ *
+ * Purpose: Create a new index in a container.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X_create_data(hid_t loc_id, H5X_class_t *idx_class, hid_t xcpl_id,
+ hid_t xapl_id)
+{
+ H5D_t *dset = NULL;
+ void *idx_handle = NULL; /* Pointer to index object created */
+ size_t metadata_size; /* Size of metadata created by plugin */
+ void *metadata; /* Metadata created by plugin that needs to be stored */
+ H5O_idxinfo_t idx_info;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(idx_class);
+ HDassert(idx_class->type == H5X_TYPE_DATA);
+
/* Get dset object */
- if (NULL == (dset = (H5D_t *) H5I_object_verify(dset_id, H5I_DATASET)))
+ if (NULL == (dset = (H5D_t *) H5I_object_verify(loc_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
/* Call create of the plugin */
if (NULL == idx_class->idx_class.data_class.create)
HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin create callback is not defined");
- if (NULL == (idx_handle = idx_class->idx_class.data_class.create(dset_id, xcpl_id, xapl_id,
+ if (NULL == (idx_handle = idx_class->idx_class.data_class.create(loc_id, xcpl_id, xapl_id,
&metadata_size, &metadata)))
HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "cannot create new plugin index");
/* Add idx_handle to dataset */
- idx_info.plugin_id = plugin_id;
+ idx_info.plugin_id = idx_class->id;
idx_info.metadata_size = metadata_size;
idx_info.metadata = metadata;
- if (FAIL == H5D_set_index(dset, 1, &idx_class, &idx_handle, &idx_info))
+ if (FAIL == H5D_set_index(dset, idx_class, idx_handle, &idx_info))
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "cannot set index");
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5X_create() */
+} /* end H5X_create_data() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_create_metadata
+ *
+ * Purpose: Create a new index in a container.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X_create_metadata(hid_t loc_id, H5X_class_t *idx_class, hid_t xcpl_id,
+ hid_t xapl_id)
+{
+ H5F_t *file = NULL;
+ void *idx_handle = NULL; /* Pointer to index object created */
+ size_t metadata_size; /* Size of metadata created by plugin */
+ void *metadata = NULL; /* Metadata created by plugin that needs to be stored */
+ H5O_idxinfo_t idx_info;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(idx_class);
+ HDassert(idx_class->type == H5X_TYPE_METADATA);
+
+ /* Get file object */
+ if (NULL == (file = (H5F_t *) H5I_object_verify(loc_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
+
+ /* Call create of the plugin */
+ if (NULL == idx_class->idx_class.metadata_class.create)
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin create callback is not defined");
+ if (NULL == (idx_handle = idx_class->idx_class.metadata_class.create(loc_id, xcpl_id, xapl_id,
+ &metadata_size, &metadata)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "cannot create new plugin index");
+
+ /* Add idx_handle to dataset */
+ idx_info.plugin_id = idx_class->id;
+ idx_info.metadata_size = metadata_size;
+ idx_info.metadata = metadata;
+ if (FAIL == H5F_set_index(file, idx_class, idx_handle, &idx_info))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "cannot set index");
+
+done:
+ H5MM_free(metadata);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_create_metadata() */
/*-------------------------------------------------------------------------
* Function: H5Xremove
@@ -530,7 +618,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Xremove(hid_t scope_id, unsigned plugin_id)
+H5Xremove(hid_t loc_id, unsigned plugin_id)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -540,11 +628,11 @@ H5Xremove(hid_t scope_id, unsigned plugin_id)
/* Check args */
if (plugin_id > H5X_PLUGIN_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid plugin identification number");
- if (NULL == H5I_object_verify(scope_id, H5I_DATASET))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (FAIL == loc_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
/* Remove index from dataset */
- if (FAIL == H5X_remove(scope_id, plugin_id))
+ if (FAIL == H5X_remove(loc_id, plugin_id))
HGOTO_ERROR(H5E_INDEX, H5E_CANTDELETE, FAIL, "unable to delete index")
done:
@@ -561,23 +649,45 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5X_remove(hid_t dset_id, unsigned plugin_id)
+H5X_remove(hid_t loc_id, unsigned plugin_id)
{
- H5D_t *dset = NULL;
+ H5I_type_t loc_type;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check args */
- HDassert(dset_id != FAIL);
+ HDassert(loc_id != FAIL);
HDassert(plugin_id <= H5X_PLUGIN_MAX);
- if (NULL == (dset = (H5D_t *) H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (H5I_BADID == (loc_type = H5I_get_type(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid type")
- /* Remove idx_handle from dataset */
- if (FAIL == H5D_remove_index(dset, plugin_id))
- HGOTO_ERROR(H5E_INDEX, H5E_CANTDELETE, FAIL, "unable to delete index")
+ switch (loc_type) {
+ case H5I_FILE:
+ {
+ H5F_t *file = NULL;
+
+ if (NULL == (file = (H5F_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+ if (FAIL == H5F_remove_index(file, plugin_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTDELETE, FAIL, "unable to delete index")
+ }
+ break;
+ case H5I_DATASET:
+ {
+ H5D_t *dset = NULL;
+
+ if (NULL == (dset = (H5D_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (FAIL == H5D_remove_index(dset, plugin_id))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTDELETE, FAIL, "unable to delete index")
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a supported type");
+ break;
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -593,19 +703,19 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Xget_count(hid_t scope_id, hsize_t *idx_count)
+H5Xget_count(hid_t loc_id, hsize_t *idx_count)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "i*h", scope_id, idx_count);
- if (NULL == H5I_object_verify(scope_id, H5I_DATASET))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (FAIL == loc_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if (!idx_count)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "idx_count is NULL");
- if (FAIL == H5X_get_count(scope_id, idx_count))
+ if (FAIL == H5X_get_count(loc_id, idx_count))
HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "cannot get index count");
done:
@@ -622,24 +732,47 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5X_get_count(hid_t dset_id, hsize_t *idx_count)
+H5X_get_count(hid_t loc_id, hsize_t *idx_count)
{
- H5D_t *dset = NULL;
- unsigned actual_count;
+ H5I_type_t loc_type;
+ H5X_class_t *idx_class = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
- HDassert(dset_id != H5I_BADID);
+ HDassert(loc_id != H5I_BADID);
HDassert(idx_count);
- if (NULL == (dset = (H5D_t *) H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (H5I_BADID == (loc_type = H5I_get_type(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid type")
- if (FAIL == H5D_get_index(dset, 1, NULL, NULL, NULL, &actual_count))
- HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ switch (loc_type) {
+ case H5I_FILE:
+ {
+ H5F_t *file = NULL;
+
+ if (NULL == (file = (H5F_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+ if (FAIL == H5F_get_index(file, &idx_class, NULL, NULL))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ }
+ break;
+ case H5I_DATASET:
+ {
+ H5D_t *dset = NULL;
+
+ if (NULL == (dset = (H5D_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (FAIL == H5D_get_index(dset, &idx_class, NULL, NULL))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a supported type");
+ break;
+ }
- *idx_count = actual_count;
+ *idx_count = (idx_class) ? 1 : 0;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -655,17 +788,16 @@ done:
*-------------------------------------------------------------------------
*/
hsize_t
-H5Xget_size(hid_t scope_id)
+H5Xget_size(hid_t loc_id)
{
hsize_t ret_value = 0; /* Return value */
FUNC_ENTER_API(0)
H5TRACE1("h", "i", scope_id);
- if (NULL == H5I_object_verify(scope_id, H5I_DATASET))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataset")
-
- if (FAIL == H5X_get_size(scope_id, &ret_value))
+ if (FAIL == loc_id)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a location")
+ if (FAIL == H5X_get_size(loc_id, &ret_value))
HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, 0, "cannot get index storage size");
done:
@@ -682,22 +814,45 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5X_get_size(hid_t dset_id, hsize_t *idx_size)
+H5X_get_size(hid_t loc_id, hsize_t *idx_size)
{
- H5D_t *dset = NULL;
+ H5I_type_t loc_type;
hsize_t actual_size = 0;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
- HDassert(dset_id != H5I_BADID);
+ HDassert(loc_id != H5I_BADID);
HDassert(idx_size);
- if (NULL == (dset = (H5D_t *) H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (H5I_BADID == (loc_type = H5I_get_type(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid type")
- if (FAIL == H5D_get_index_size(dset, &actual_size))
- HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ switch (loc_type) {
+ case H5I_FILE:
+ {
+ H5F_t *file = NULL;
+
+ if (NULL == (file = (H5F_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+ if (FAIL == H5F_get_index_size(file, &actual_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ }
+ break;
+ case H5I_DATASET:
+ {
+ H5D_t *dset = NULL;
+
+ if (NULL == (dset = (H5D_t *) H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ if (FAIL == H5D_get_index_size(dset, &actual_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "plugin is not registered");
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a supported type");
+ break;
+ }
*idx_size = actual_size;
diff --git a/src/H5Xmeta_dummy.c b/src/H5Xmeta_dummy.c
new file mode 100644
index 0000000..5235522
--- /dev/null
+++ b/src/H5Xmeta_dummy.c
@@ -0,0 +1,1439 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: Dummy index routines.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Xprivate.h" /* Index */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h"
+#include "H5Qprivate.h"
+#include "H5Sprivate.h"
+/* TODO using private headers but could use public ones */
+
+//#define H5Q_FRIEND
+//#include "H5Qpkg.h" /* To re-use H5Q_QUEUE */
+
+#define H5R_FRIEND
+#include "H5Rpkg.h" /* (Tmp) To re-use H5R__get_obj_name */
+
+/****************/
+/* Local Macros */
+/****************/
+//#define H5X_DUMMY_DEBUG
+
+#ifdef H5X_DUMMY_DEBUG
+#define H5X_DUMMY_LOG_DEBUG(...) do { \
+ fprintf(stdout, " # %s(): ", __func__); \
+ fprintf(stdout, __VA_ARGS__); \
+ fprintf(stdout, "\n"); \
+ fflush(stdout); \
+ } while (0)
+#else
+#define H5X_DUMMY_LOG_DEBUG(...) do { \
+ } while (0)
+#endif
+
+/*
+ * Singly-linked Tail queue declarations. (from sys/queue.h)
+ */
+#define H5Q_QUEUE_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first; /* first element */ \
+ struct type **stqh_last; /* addr of last next element */ \
+ size_t n_elem; /* number of elements */ \
+}
+
+#define H5Q_QUEUE_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first, 0 }
+
+#define H5Q_QUEUE_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define H5Q_QUEUE_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+ (head)->n_elem = 0; \
+} while (/*CONSTCOND*/0)
+
+#define H5Q_QUEUE_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+ (head)->n_elem++; \
+} while (/*CONSTCOND*/0)
+
+#define H5Q_QUEUE_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->n_elem++; \
+} while (/*CONSTCOND*/0)
+
+#define H5Q_QUEUE_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) { \
+ (head)->stqh_last = &(head)->stqh_first; \
+ (head)->n_elem--; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define H5Q_QUEUE_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ H5Q_QUEUE_REMOVE_HEAD((head), field); \
+ } else { \
+ struct type *curelm = (head)->stqh_first; \
+ while (curelm->field.stqe_next != (elm)) \
+ curelm = curelm->field.stqe_next; \
+ if ((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ (head)->n_elem--; \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define H5Q_QUEUE_FOREACH(var, head, field) \
+ for ((var) = ((head)->stqh_first); \
+ (var); \
+ (var) = ((var)->field.stqe_next))
+
+#define H5Q_QUEUE_CONCAT(head1, head2) do { \
+ if (!H5Q_QUEUE_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ (head1)->n_elem += (head2)->n_elem; \
+ H5Q_QUEUE_INIT((head2)); \
+ } \
+} while (/*CONSTCOND*/0)
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define H5Q_QUEUE_EMPTY(head) ((head)->stqh_first == NULL)
+#define H5Q_QUEUE_FIRST(head) ((head)->stqh_first)
+#define H5Q_QUEUE_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define H5X_DUMMY_METADATA_TYPES 3
+#define H5X_DUMMY_MAX_NAME_LEN (64 * 1024)
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+typedef struct {
+ hid_t type;
+ void *value;
+} H5X_dummy_elem_t;
+
+typedef struct H5X_dummy_entry_t H5X_dummy_entry_t;
+
+struct H5X_dummy_entry_t {
+ H5Q_type_t type; /* Query type */
+ union { /* Key */
+ H5X_dummy_elem_t elem;
+ char *name;
+ } key;
+ href_t ref; /* External reference */
+ H5Q_QUEUE_ENTRY(H5X_dummy_entry_t) entry;
+};
+
+typedef H5Q_QUEUE_HEAD(H5X_dummy_head_t, H5X_dummy_entry_t) H5X_dummy_head_t;
+
+typedef struct {
+ H5X_dummy_head_t attr_values;
+ H5X_dummy_head_t attr_names;
+ H5X_dummy_head_t link_names;
+} H5X_dummy_metadata_t;
+
+typedef struct {
+ const char *filename;
+ const char *loc_name;
+ H5X_dummy_metadata_t *metadata;
+} H5X_dummy_index_attr_arg_t;
+
+typedef struct {
+ H5X_dummy_index_attr_arg_t *attr_args;
+ const char *attr_name;
+} H5X_dummy_index_attr_elem_arg_t;
+
+typedef struct H5X_dummy_t {
+// hid_t dataset_id;
+// hid_t idx_anon_id;
+// void *idx_token;
+// size_t idx_token_size;
+ H5X_dummy_metadata_t metadata;
+} H5X_dummy_t;
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+static herr_t H5X__dummy_index(hid_t oid, const char *name, const H5O_info_t *oinfo,
+ void *udata);
+static herr_t H5X__dummy_index_link_name(H5X_dummy_metadata_t *metadata, hid_t loc_id,
+ const char *name, const H5O_info_t *oinfo);
+static herr_t H5X__dummy_index_attrs(H5X_dummy_metadata_t *metadata, hid_t loc_id,
+ const char *name);
+static herr_t H5X__dummy_index_attr(hid_t loc_id, const char *attr_name,
+ const H5A_info_t H5_ATTR_UNUSED *ainfo, void *udata);
+static herr_t H5X__dummy_index_attr_name(const char *attr_name, void *udata);
+static herr_t H5X__dummy_index_attr_value(hid_t loc_id, const char *attr_name,
+ void *udata);
+static herr_t H5X__dummy_index_attr_value_iterate(void *elem, hid_t type_id,
+ unsigned ndim, const hsize_t *point, void *udata);
+static herr_t H5X__dummy_metadata_add(H5X_dummy_metadata_t *metadata,
+ href_t ref, H5Q_type_t type, ...);
+static herr_t H5X__dummy_metadata_free(H5X_dummy_metadata_t *metadata);
+static herr_t H5X__dummy_metadata_add_entry(H5X_dummy_head_t *head,
+ H5X_dummy_entry_t *entry);
+static herr_t H5X__dummy_metadata_remove_entries(H5X_dummy_head_t *head);
+static herr_t H5X__dummy_metadata_write(H5X_dummy_metadata_t *metadata,
+ hid_t loc_id, size_t *plugin_metadata_size, void **plugin_metadata);
+static herr_t H5X__dummy_metadata_read(hid_t loc_id,
+ size_t plugin_metadata_size, void *plugin_metadata,
+ H5X_dummy_metadata_t *metadata);
+static herr_t H5X__dummy_serialize_metadata(hid_t dset_ids[], void *buf,
+ size_t *buf_size);
+static herr_t H5X__dummy_deserialize_metadata(hid_t file_id, void *buf,
+ size_t buf_size, hid_t *dset_ids[]);
+static herr_t H5X__dummy_index_rebuild(H5X_dummy_metadata_t *metadata,
+ void *bufs[], size_t nelmts[], hid_t type_ids[]);
+static herr_t H5X__dummy_metadata_query(H5X_dummy_metadata_t *metadata,
+ hid_t query_id, H5X_dummy_head_t *result);
+static herr_t H5X__dummy_metadata_query_singleton(H5X_dummy_metadata_t *metadata,
+ hid_t query_id, H5X_dummy_head_t *result);
+static herr_t H5X__dummy_metadata_query_combine(H5Q_combine_op_t combine_op,
+ H5X_dummy_head_t *result1, H5X_dummy_head_t *result2,
+ H5X_dummy_head_t *result);
+
+static void *H5X__dummy_create(hid_t loc_id, hid_t xcpl_id, hid_t xapl_id,
+ size_t *metadata_size, void **metadata);
+static herr_t H5X__dummy_remove(hid_t loc_id, size_t metadata_size,
+ void *metadata);
+static void *H5X__dummy_open(hid_t loc_id, hid_t xapl_id, size_t
+ metadata_size, void *metadata);
+static herr_t H5X__dummy_close(void *idx_handle);
+static herr_t H5X__dummy_insert_entry(void *idx_handle, hid_t obj_id,
+ H5Q_type_t key_type, H5Q_elem_t *key, hid_t xxpl_id);
+static herr_t H5X__dummy_remove_entry(void *idx_handle, hid_t obj_id,
+ H5Q_type_t key_type, H5Q_elem_t *key, hid_t xxpl_id);
+static herr_t H5X__dummy_query(void *idx_handle, hid_t query_id, hid_t xxpl_id,
+ size_t *ref_count, href_t *refs[]);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Dummy index class */
+const H5X_class_t H5X_META_DUMMY[1] = {{
+ H5X_CLASS_T_VERS, /* (From the H5Xpublic.h header file) */
+ H5X_PLUGIN_META_DUMMY, /* (Or whatever number is assigned) */
+ "dummy index plugin", /* Whatever name desired */
+ H5X_TYPE_METADATA, /* This plugin operates on metadata */
+ {{
+ H5X__dummy_create, /* create */
+ H5X__dummy_remove, /* remove */
+ H5X__dummy_open, /* open */
+ H5X__dummy_close, /* close */
+ H5X__dummy_insert_entry, /* insert_entry */
+ H5X__dummy_remove_entry, /* remove_entry */
+ H5X__dummy_query, /* query */
+ NULL /* get_size */
+ }}
+}};
+
+static void
+printf_ref(href_t ref)
+{
+ char obj_name[H5X_DUMMY_MAX_NAME_LEN];
+
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, ref, obj_name, H5X_DUMMY_MAX_NAME_LEN);
+ if (H5Rget_type(ref) == H5R_EXT_ATTR) {
+ char attr_name[H5X_DUMMY_MAX_NAME_LEN];
+ H5R__get_attr_name(NULL, ref, attr_name, H5X_DUMMY_MAX_NAME_LEN);
+ H5X_DUMMY_LOG_DEBUG("Attribute reference: %s, %s", obj_name, attr_name);
+ } else {
+ H5X_DUMMY_LOG_DEBUG("Object reference: %s", obj_name);
+ }
+}
+
+static herr_t
+H5X__dummy_index(hid_t oid, const char *name, const H5O_info_t *oinfo,
+ void *udata)
+{
+ H5X_dummy_metadata_t *metadata = (H5X_dummy_metadata_t *) udata;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(name);
+ HDassert(oinfo);
+ HDassert(metadata);
+
+ /* Index link names */
+ if (FAIL == H5X__dummy_index_link_name(metadata, oid, name, oinfo))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTAPPEND, FAIL, "can't add link name");
+
+ /* Index attribute names/values */
+ if (FAIL == H5X__dummy_index_attrs(metadata, oid, name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't apply data query to object");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index */
+
+static herr_t
+H5X__dummy_index_link_name(H5X_dummy_metadata_t *metadata, hid_t loc_id,
+ const char *name, const H5O_info_t *oinfo)
+{
+ href_t ref;
+ const char *link_name = NULL;
+ const char *trimmed_path = NULL;
+ char file_name[H5X_DUMMY_MAX_NAME_LEN];
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(metadata);
+ HDassert(name);
+ HDassert(oinfo);
+
+ trimmed_path = HDstrrchr(name, '/');
+ link_name = (trimmed_path) ? ++trimmed_path : name;
+
+ if ((oinfo->type != H5O_TYPE_GROUP) && (oinfo->type != H5O_TYPE_DATASET))
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized object type");
+
+ /* Get file name */
+ if (H5Fget_name(loc_id, file_name, H5X_DUMMY_MAX_NAME_LEN) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file name");
+
+ /* Keep object reference */
+ if (NULL == (ref = H5R_create_ext_object(file_name, name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create object reference");
+ if (FAIL == H5X__dummy_metadata_add(metadata, ref, H5Q_TYPE_LINK_NAME, link_name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_link_name */
+
+static herr_t
+H5X__dummy_index_attrs(H5X_dummy_metadata_t *metadata, hid_t loc_id,
+ const char *name)
+{
+ H5X_dummy_index_attr_arg_t attr_args;
+ hid_t obj_id = FAIL;
+ char file_name[H5X_DUMMY_MAX_NAME_LEN];
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(metadata);
+ HDassert(name);
+
+ /* Get file name */
+ if (H5Fget_name(loc_id, file_name, H5X_DUMMY_MAX_NAME_LEN) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file name");
+
+ /* Build attribute operator info */
+ attr_args.filename = file_name;
+ attr_args.loc_name = name;
+ attr_args.metadata = metadata;
+
+ if (0 == HDstrcmp(name, ".")) {
+ obj_id = loc_id;
+ } else {
+ if (FAIL == (obj_id = H5Oopen(loc_id, name, H5P_DEFAULT)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open object");
+ }
+
+ /* Iterate over attributes */
+ if (FAIL == (ret_value = H5Aiterate(obj_id, H5_INDEX_NAME, H5_ITER_NATIVE,
+ NULL, H5X__dummy_index_attr, &attr_args)))
+ HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes");
+
+done:
+ if ((obj_id != FAIL) && (obj_id != loc_id) && (FAIL == H5Oclose(obj_id)))
+ HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_attrs */
+
+static herr_t
+H5X__dummy_index_attr(hid_t loc_id, const char *attr_name,
+ const H5A_info_t H5_ATTR_UNUSED *ainfo, void *udata)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(attr_name);
+ HDassert(udata);
+
+ if (FAIL == H5X__dummy_index_attr_name(attr_name, udata))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't apply attr name query to object");
+
+ if (FAIL == H5X__dummy_index_attr_value(loc_id, attr_name, udata))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't apply attr name query to object");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_attr */
+
+static herr_t
+H5X__dummy_index_attr_name(const char *attr_name, void *udata)
+{
+ H5X_dummy_index_attr_arg_t *args = (H5X_dummy_index_attr_arg_t *) udata;
+ href_t ref;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(attr_name);
+ HDassert(args);
+
+ /* Keep attribute reference */
+ if (NULL == (ref = H5R_create_ext_attr(args->filename, args->loc_name, attr_name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference");
+ if (FAIL == H5X__dummy_metadata_add(args->metadata, ref, H5Q_TYPE_ATTR_NAME, attr_name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_attr_name */
+
+static herr_t
+H5X__dummy_index_attr_value(hid_t loc_id, const char *attr_name, void *udata)
+{
+ H5X_dummy_index_attr_arg_t *args = (H5X_dummy_index_attr_arg_t *) udata;
+ void *buf = NULL;
+ size_t buf_size;
+ hid_t attr_id = FAIL;
+ hid_t type_id = FAIL;
+ hid_t space_id = FAIL;
+ size_t nelmts, elmt_size;
+ H5X_dummy_index_attr_elem_arg_t iter_args;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(attr_name);
+ HDassert(args);
+
+ /* Open attribute */
+ if (FAIL == (attr_id = H5Aopen(loc_id, attr_name, H5P_DEFAULT)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute");
+
+ /* Get attribute info */
+ if (FAIL == (type_id = H5Aget_type(attr_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get attribute datatype");
+ if (FAIL == (space_id = H5Aget_space(attr_id)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get attribute dataspace");
+ if (0 == (nelmts = (size_t) H5Sget_select_npoints(space_id)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements");
+ if (0 == (elmt_size = H5Tget_size(type_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid size of element");
+
+ /* Allocate buffer to hold data */
+ buf_size = nelmts * elmt_size;
+ if (NULL == (buf = H5MM_malloc(buf_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* Read data */
+ if (FAIL == H5Aread(attr_id, type_id, buf))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute");
+
+ iter_args.attr_args = args;
+ iter_args.attr_name = attr_name;
+
+ /* Iterate over attribute elements to compare values */
+ if (FAIL == H5Diterate(buf, type_id, space_id, H5X__dummy_index_attr_value_iterate, &iter_args))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "unable to compare attribute elements");
+
+done:
+ H5MM_free(buf);
+ if (attr_id != FAIL) H5Aclose(attr_id);
+ if (type_id != FAIL) H5Tclose(type_id);
+ if (space_id != FAIL) H5Sclose(space_id);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_attr_value */
+
+static herr_t
+H5X__dummy_index_attr_value_iterate(void *elem, hid_t type_id,
+ unsigned H5_ATTR_UNUSED ndim, const hsize_t H5_ATTR_UNUSED *point, void *udata)
+{
+ H5X_dummy_index_attr_elem_arg_t *args = (H5X_dummy_index_attr_elem_arg_t *) udata;
+ href_t ref;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(elem);
+ HDassert(args);
+
+ /* Keep attribute reference */
+ if (NULL == (ref = H5R_create_ext_attr(args->attr_args->filename, args->attr_args->loc_name, args->attr_name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference");
+ if (FAIL == H5X__dummy_metadata_add(args->attr_args->metadata, ref, H5Q_TYPE_ATTR_VALUE, type_id, elem))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_index_attr_value_iterate */
+
+static herr_t
+H5X__dummy_metadata_add(H5X_dummy_metadata_t *metadata, href_t ref, H5Q_type_t type, ...)
+{
+ va_list ap;
+ H5X_dummy_entry_t *entry;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(metadata);
+ HDassert(ref);
+
+ va_start(ap, type);
+
+ if (NULL == (entry = (H5X_dummy_entry_t *) H5MM_malloc(sizeof(H5X_dummy_entry_t))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry");
+ entry->ref = ref;
+ entry->type = type;
+
+ switch (type) {
+ case H5Q_TYPE_ATTR_VALUE:
+ {
+ hid_t datatype_id;
+ size_t datatype_size;
+ const void *value;
+
+ /* Get arguments */
+ datatype_id = va_arg(ap, hid_t);
+ value = va_arg(ap, const void *);
+
+ HDassert(datatype_id != FAIL);
+ HDassert(value);
+
+ if (FAIL == (entry->key.elem.type = H5Tget_native_type(datatype_id, H5T_DIR_DEFAULT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy attribute type");
+ if (0 == (datatype_size = H5Tget_size(entry->key.elem.type)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size");
+ if (NULL == (entry->key.elem.value = H5MM_malloc(datatype_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer");
+ HDmemcpy(entry->key.elem.value, value, datatype_size);
+ H5Q_QUEUE_INSERT_TAIL(&metadata->attr_values, entry, entry);
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ const char *attr_name;
+
+ /* Get arguments */
+ attr_name = va_arg(ap, const char *);
+
+ HDassert(attr_name);
+
+ entry->key.name = H5MM_strdup(attr_name);
+ H5Q_QUEUE_INSERT_TAIL(&metadata->attr_names, entry, entry);
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ const char *link_name;
+
+ /* Get arguments */
+ link_name = va_arg(ap, const char *);
+
+ HDassert(link_name);
+
+ entry->key.name = H5MM_strdup(link_name);
+ H5Q_QUEUE_INSERT_TAIL(&metadata->link_names, entry, entry);
+ }
+ break;
+ case H5Q_TYPE_MISC:
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+ break;
+ }
+
+done:
+ va_end(ap);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_add */
+
+static herr_t
+H5X__dummy_metadata_free(H5X_dummy_metadata_t *metadata)
+{
+ H5X_dummy_head_t *entries[H5X_DUMMY_METADATA_TYPES] = { &metadata->attr_names,
+ &metadata->attr_values, &metadata->link_names };
+ herr_t ret_value = SUCCEED; /* Return value */
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ while (!H5Q_QUEUE_EMPTY(entries[i])) {
+ H5X_dummy_entry_t *entry = H5Q_QUEUE_FIRST(entries[i]);
+ H5Q_QUEUE_REMOVE_HEAD(entries[i], entry);
+
+ if (FAIL == H5Rdestroy(entry->ref))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy reference");
+ switch (entry->type) {
+ case H5Q_TYPE_ATTR_VALUE:
+ if (FAIL == H5Tclose(entry->key.elem.type))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close datatype");
+ entry->key.elem.value = H5MM_xfree(entry->key.elem.value);
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ case H5Q_TYPE_LINK_NAME:
+ entry->key.name = H5MM_xfree(entry->key.name);
+ break;
+ case H5Q_TYPE_MISC:
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+ break;
+ }
+ H5MM_free(entry);
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_free */
+
+static herr_t
+H5X__dummy_metadata_add_entry(H5X_dummy_head_t *head, H5X_dummy_entry_t *entry)
+{
+ H5X_dummy_entry_t *new_entry;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(head);
+ HDassert(entry);
+
+ if (NULL == (new_entry = (H5X_dummy_entry_t *) H5MM_malloc(sizeof(H5X_dummy_entry_t))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry");
+ HDmemcpy(new_entry, entry, sizeof(H5X_dummy_entry_t));
+ H5Q_QUEUE_INSERT_TAIL(head, new_entry, entry);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_add_entry */
+
+static herr_t
+H5X__dummy_metadata_remove_entries(H5X_dummy_head_t *head)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(head);
+
+ while (!H5Q_QUEUE_EMPTY(head)) {
+ H5X_dummy_entry_t *entry = H5Q_QUEUE_FIRST(head);
+ H5Q_QUEUE_REMOVE_HEAD(head, entry);
+ H5MM_free(entry);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_remove_entries */
+
+static herr_t
+H5X__dummy_metadata_write(H5X_dummy_metadata_t *metadata, hid_t file_id,
+ size_t *plugin_metadata_size, void **plugin_metadata)
+{
+ hid_t dset_ids[H5X_DUMMY_METADATA_TYPES] = {FAIL, FAIL, FAIL};
+ hid_t mem_space_id = FAIL;
+ hid_t space_id = FAIL;
+ H5X_dummy_head_t *entries[H5X_DUMMY_METADATA_TYPES] = { &metadata->attr_names,
+ &metadata->attr_values, &metadata->link_names };
+ hid_t type_ids[H5X_DUMMY_METADATA_TYPES] = { H5T_STD_REF_EXT_ATTR,
+ FAIL, H5T_STD_REF_EXT_OBJ };
+ herr_t ret_value = SUCCEED; /* Return value */
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Iterate over reference types and write references if any */
+ /* We only need to store attribute/object references and attribute values */
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ H5X_dummy_entry_t *entry = NULL;
+ hsize_t n_elem = entries[i]->n_elem;
+ hsize_t start = 0;
+
+ if (!n_elem)
+ continue;
+
+ /* Create dataspace */
+ if (FAIL == (space_id = H5Screate_simple(1, &n_elem, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace");
+
+ /* Create the new dataset & get its ID */
+ if (H5Q_QUEUE_FIRST(entries[i])->type == H5Q_TYPE_ATTR_VALUE)
+ type_ids[i] = H5Q_QUEUE_FIRST(entries[i])->key.elem.type;
+ if (FAIL == (dset_ids[i] = H5Dcreate_anon(file_id, type_ids[i],
+ space_id, H5P_DEFAULT, H5P_DEFAULT)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL, "can't create anonymous dataset");
+
+ /* Increment refcount so that anonymous dataset is persistent */
+ if (FAIL == H5Oincr_refcount(dset_ids[i]))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTINC, FAIL, "can't increment dataset refcount");
+
+ /* Iterate over reference entries in view */
+ H5Q_QUEUE_FOREACH(entry, entries[i], entry) {
+ hsize_t count = 1;
+ const void *buf = (entry->type == H5Q_TYPE_ATTR_VALUE) ? entry->key.elem.value : &entry->ref;
+
+ if (FAIL == (mem_space_id = H5Screate_simple(1, &count, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace");
+ if (FAIL == H5Sselect_hyperslab(space_id, H5S_SELECT_SET, &start, NULL, &count, NULL))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
+ if (FAIL == H5Dwrite(dset_ids[i], type_ids[i], mem_space_id,
+ space_id, H5P_DEFAULT, buf))
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write dataset");
+ if (FAIL == H5Sclose(mem_space_id))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataspace");
+ mem_space_id = FAIL;
+
+ /* Increment reference position in file */
+ start++;
+ }
+ if (FAIL == H5Sclose(space_id))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataspace");
+ space_id = FAIL;
+ }
+
+ /* Serialize metadata */
+ if (FAIL == H5X__dummy_serialize_metadata(dset_ids, NULL, plugin_metadata_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get plugin metadata size");
+ if (NULL == (*plugin_metadata = H5MM_malloc(*plugin_metadata_size)))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate plugin metadata");
+ if (FAIL == H5X__dummy_serialize_metadata(dset_ids, *plugin_metadata, plugin_metadata_size))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTENCODE, FAIL, "can't serialize plugin metadata");
+
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ if (FAIL == H5Dclose(dset_ids[i]))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataset");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_write */
+
+
+static herr_t
+H5X__dummy_metadata_read(hid_t file_id, size_t plugin_metadata_size,
+ void *plugin_metadata, H5X_dummy_metadata_t *metadata)
+{
+ hid_t *dset_ids;
+ herr_t ret_value = SUCCEED; /* Return value */
+ void *bufs[H5X_DUMMY_METADATA_TYPES];
+ size_t nelmts[H5X_DUMMY_METADATA_TYPES];
+ hid_t type_ids[H5X_DUMMY_METADATA_TYPES];
+ int i;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Deserialize metadata and get anon dataset IDs */
+ if (FAIL == H5X__dummy_deserialize_metadata(file_id, plugin_metadata, plugin_metadata_size,
+ &dset_ids))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTDECODE, FAIL, "can't deserialize plugin metadata");
+
+ /* Iterate over metadata index types */
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ hid_t type_id = FAIL, space_id = FAIL;
+ size_t elmt_size;
+
+ if (FAIL == (type_id = H5Dget_type(dset_ids[i])))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get datatype");
+ if (FAIL == (space_id = H5Dget_space(dset_ids[i])))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get datatype");
+ if (0 == (nelmts[i] = (size_t) H5Sget_select_npoints(space_id)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements");
+ if (0 == (elmt_size = H5Tget_size(type_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid size of element");
+
+ /* Allocate buffer to hold data */
+ if (NULL == (bufs[i] = H5MM_malloc(nelmts[i] * elmt_size)))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ /* Read data from dataset */
+ if (FAIL == H5Dread(dset_ids[i], type_id, H5S_ALL, space_id,
+ H5P_DEFAULT, bufs[i]))
+ HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read index data");
+
+ if (FAIL == H5Sclose(space_id))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataspace");
+ }
+
+ /* Rebuild metadata index */
+ if (FAIL == H5X__dummy_index_rebuild(metadata, bufs, nelmts, type_ids))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTINIT, FAIL, "unable to rebuild metadata index");
+
+ /* Close anon datasets */
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ H5MM_free(bufs[i]);
+ if (FAIL == H5Tclose(type_ids[i]))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close datatype");
+ if (FAIL == H5Dclose(dset_ids[i]))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataset");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_read */
+
+static herr_t
+H5X__dummy_serialize_metadata(hid_t dset_ids[], void *buf, size_t *buf_size)
+{
+ uint8_t *p = buf;
+ size_t metadata_size = 3 * sizeof(haddr_t);
+ int i;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ /* Encode metadata token info */
+ if (p) {
+ H5O_info_t dset_info;
+
+ /* Get addr info for dataset */
+ if (FAIL == H5Oget_info(dset_ids[i], &dset_info))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get dataset info");
+
+ /* TODO use H5F_addr_encode instead */
+ HDmemcpy(p, &dset_info.addr, sizeof(haddr_t));
+ p += sizeof(haddr_t);
+ }
+ }
+
+ if (buf_size) *buf_size = metadata_size;
+
+ done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_serialize_metadata */
+
+static herr_t
+H5X__dummy_deserialize_metadata(hid_t file_id, void *buf, size_t buf_size,
+ hid_t *dset_ids[])
+{
+ uint8_t *p = buf;
+ int i;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(buf);
+ HDassert(buf_size);
+ HDassert(dset_ids);
+
+ for (i = 0; i < H5X_DUMMY_METADATA_TYPES; i++) {
+ /* Decode index token info */
+ if (FAIL == (*dset_ids[i] = H5Oopen_by_addr(file_id, *((haddr_t *) p))))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTOPENOBJ, FAIL, "can't open anonymous dataset");
+ p += sizeof(haddr_t);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5X__dummy_deserialize_metadata */
+
+static herr_t
+H5X__dummy_index_rebuild(H5X_dummy_metadata_t *metadata, void *bufs[],
+ size_t nelmts[], hid_t type_ids[])
+{
+// H5X_dummy_head_t *entries[H5X_DUMMY_METADATA_TYPES] = { &metadata->attr_names,
+// &metadata->attr_values, &metadata->link_names };
+// href_t *link_refs;
+// href_t *attr_refs;
+// void **attr_values;
+// hid_t attr_native_id;
+// int i;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(metadata);
+ HDassert(bufs);
+ HDassert(nelmts);
+ HDassert(type_ids);
+
+// attr_refs = bufs[0];
+// attr_values = bufs[1];
+// link_refs = bufs[2];
+// attr_native_id = H5Tget_native_type(type_ids[1], H5T_DIR_DEFAULT);
+//
+// for (i = 0; i < nelmts[0]; i++) {
+// href_t ref;
+// char attr_name[H5X_DUMMY_MAX_NAME_LEN];
+// char filename[H5X_DUMMY_MAX_NAME_LEN];
+// char pathname[H5X_DUMMY_MAX_NAME_LEN];
+//
+// H5R__get_attr_name(NULL, attr_refs[i], attr_name, H5X_DUMMY_MAX_NAME_LEN);
+// H5R__get_obj_name(NULL, attr_refs[i], pathname, H5X_DUMMY_MAX_NAME_LEN);
+// H5Rget_file_name(attr_refs[i], attr_name, H5X_DUMMY_MAX_NAME_LEN);
+// ref = H5R_create_ext_attr(filename, pathname, attr_name);
+// if (FAIL == H5X__dummy_metadata_add(metadata, attr_refs[i], H5Q_TYPE_ATTR_NAME, attr_name))
+// HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+// }
+
+//done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5X__dummy_index_rebuild */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_dummy_create
+ *
+ * Purpose: This function creates a new instance of a dummy plugin index.
+ *
+ * Return: Success: Pointer to the new index
+ * Failure: NULL
+ *
+ *------------------------------------------------------------------------
+ */
+static void *
+H5X__dummy_create(hid_t loc_id, hid_t H5_ATTR_UNUSED xcpl_id,
+ hid_t H5_ATTR_UNUSED xapl_id, size_t *metadata_size, void **metadata)
+{
+ H5X_dummy_t *dummy = NULL;
+ hid_t file_id;
+ void *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X_dummy_create");
+
+ /* Create new dummy instance */
+ if (NULL == (dummy = (H5X_dummy_t *) H5MM_malloc(sizeof(H5X_dummy_t))))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate dummy struct");
+ H5Q_QUEUE_INIT(&dummy->metadata.attr_names);
+ H5Q_QUEUE_INIT(&dummy->metadata.attr_values);
+ H5Q_QUEUE_INIT(&dummy->metadata.link_names);
+
+ /* Get file ID */
+ file_id = loc_id; /* TODO for now */
+
+ /* Visit file */
+ if (FAIL == H5Ovisit(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, H5X__dummy_index,
+ &dummy->metadata))
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, NULL, "object visitation failed");
+
+ H5X_DUMMY_LOG_DEBUG("###########################");
+ if (!H5Q_QUEUE_EMPTY(&dummy->metadata.attr_names))
+ H5X_DUMMY_LOG_DEBUG("Indexed %zu attributes names", dummy->metadata.attr_names.n_elem);
+ if (!H5Q_QUEUE_EMPTY(&dummy->metadata.attr_values))
+ H5X_DUMMY_LOG_DEBUG("Indexed %zu attributes values", dummy->metadata.attr_values.n_elem);
+ if (!H5Q_QUEUE_EMPTY(&dummy->metadata.link_names))
+ H5X_DUMMY_LOG_DEBUG("Indexed %zu link names", dummy->metadata.link_names.n_elem);
+ H5X_dummy_entry_t *entry;
+ H5Q_QUEUE_FOREACH(entry, &dummy->metadata.attr_names, entry) {
+ H5X_DUMMY_LOG_DEBUG("Indexed attribute name: %s", (const char *) entry->key.name);
+ }
+ H5Q_QUEUE_FOREACH(entry, &dummy->metadata.attr_values, entry) {
+ H5X_DUMMY_LOG_DEBUG("Indexed attribute value: %d", *((int *) entry->key.elem.value));
+ }
+ H5Q_QUEUE_FOREACH(entry, &dummy->metadata.link_names, entry) {
+ H5X_DUMMY_LOG_DEBUG("Indexed link name: %s", (const char *) entry->key.name);
+ }
+ H5X_DUMMY_LOG_DEBUG("###########################");
+
+ /* Write index metadata */
+ if (FAIL == H5X__dummy_metadata_write(&dummy->metadata, file_id, metadata_size, metadata))
+ HGOTO_ERROR(H5E_INDEX, H5E_WRITEERROR, NULL, "can't write metadata");
+
+ ret_value = dummy;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_dummy_create() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_dummy_remove
+ *
+ * Purpose: This function removes the dummy plugin index from the file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X__dummy_remove(hid_t H5_ATTR_UNUSED file_id, size_t H5_ATTR_UNUSED metadata_size,
+ void H5_ATTR_UNUSED *metadata)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X_dummy_remove");
+
+ /* TODO Does not do anything */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_dummy_remove() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_dummy_open
+ *
+ * Purpose: This function opens an already existing dummy index from a file.
+ *
+ * Return: Success: Pointer to the index
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5X__dummy_open(hid_t loc_id, hid_t H5_ATTR_UNUSED xapl_id, size_t metadata_size,
+ void *metadata)
+{
+ hid_t file_id;
+ H5X_dummy_t *dummy = NULL;
+ void *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X_dummy_open");
+
+ if (!metadata_size)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL metadata size");
+ if (!metadata)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "NULL metadata");
+
+ if (NULL == (dummy = (H5X_dummy_t *) H5MM_malloc(sizeof(H5X_dummy_t))))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate dummy struct");
+
+ /* Get file ID */
+ file_id = loc_id; /* TODO for now */
+
+ if (FAIL == H5X__dummy_metadata_read(file_id, metadata_size, metadata,
+ &dummy->metadata))
+ HGOTO_ERROR(H5E_INDEX, H5E_READERROR, NULL, "can't read metadata");
+
+ ret_value = dummy;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_dummy_open() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_dummy_close
+ *
+ * Purpose: This function closes a dummy index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X__dummy_close(void *idx_handle)
+{
+ H5X_dummy_t *dummy = (H5X_dummy_t *) idx_handle;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X_dummy_close");
+
+ if (NULL == dummy)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL index handle");
+
+ /* Free metadata */
+ if (FAIL == H5X__dummy_metadata_free(&dummy->metadata))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTFREE, FAIL, "cannot free metadata");
+
+ H5MM_free(dummy);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_dummy_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X__dummy_insert_entry
+ *
+ * Purpose: This function insert a new entry in the dummy plugin index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X__dummy_insert_entry(void *idx_handle, hid_t obj_id, H5Q_type_t key_type,
+ H5Q_elem_t *key, hid_t H5_ATTR_UNUSED xxpl_id)
+{
+ H5X_dummy_t *dummy = (H5X_dummy_t *) idx_handle;
+ char file_name[H5X_DUMMY_MAX_NAME_LEN];
+ char loc_name[H5X_DUMMY_MAX_NAME_LEN];
+ href_t ref;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X__dummy_insert_entry");
+
+ if (NULL == dummy)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL index handle");
+
+ if (H5Fget_name(obj_id, file_name, H5X_DUMMY_MAX_NAME_LEN) < 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get file name");
+ if (H5Iget_name(obj_id, loc_name, H5X_DUMMY_MAX_NAME_LEN) < 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get location name");
+
+ switch (key_type) {
+ case H5Q_TYPE_ATTR_VALUE:
+ {
+ char attr_name[H5X_DUMMY_MAX_NAME_LEN];
+
+ if (H5Aget_name(obj_id, H5X_DUMMY_MAX_NAME_LEN, attr_name) < 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get attribute name");
+
+ /* Keep attribute reference */
+ if (NULL == (ref = H5R_create_ext_attr(file_name, loc_name, attr_name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference");
+ if (FAIL == H5X__dummy_metadata_add(&dummy->metadata, ref, H5Q_TYPE_ATTR_VALUE, key->value.type, key->value.value))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ /* Keep attribute reference */
+ if (NULL == (ref = H5R_create_ext_attr(file_name, loc_name, key->name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference");
+ if (FAIL == H5X__dummy_metadata_add(&dummy->metadata, ref, H5Q_TYPE_ATTR_NAME, key->name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ /* Keep object reference */
+ if (NULL == (ref = H5R_create_ext_object(file_name, loc_name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create object reference");
+ if (FAIL == H5X__dummy_metadata_add(&dummy->metadata, ref, H5Q_TYPE_LINK_NAME, key->name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+ }
+ break;
+ case H5Q_TYPE_MISC:
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_insert_entry() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X__dummy_remove_entry
+ *
+ * Purpose: This function removes an entry from the dummy plugin index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X__dummy_remove_entry(void H5_ATTR_UNUSED *idx_handle, hid_t H5_ATTR_UNUSED obj_id,
+ H5Q_type_t H5_ATTR_UNUSED key_type, H5Q_elem_t H5_ATTR_UNUSED *key,
+ hid_t H5_ATTR_UNUSED xxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X__dummy_remove_entry");
+
+ /* TODO Does not do anything */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_insert_entry() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5X_dummy_query
+ *
+ * Purpose: This function queries a dummy index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5X__dummy_query(void *idx_handle, hid_t query_id, hid_t H5_ATTR_UNUSED xxpl_id,
+ size_t *ref_count, href_t *refs[])
+{
+ H5X_dummy_t *dummy = (H5X_dummy_t *) idx_handle;
+ H5X_dummy_head_t query_result = H5Q_QUEUE_HEAD_INITIALIZER(query_result);
+ href_t *ref_buf = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ H5X_DUMMY_LOG_DEBUG("Calling H5X_dummy_query");
+
+ if (NULL == dummy)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL index handle");
+
+ /* We assume here that the queries passed only operate on metadata */
+ if (FAIL == H5X__dummy_metadata_query(&dummy->metadata, query_id, &query_result))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, FAIL, "can't query metadata");
+
+// H5X_DUMMY_LOG_DEBUG("###########################");
+// if (!H5Q_QUEUE_EMPTY(&query_result)) {
+// H5X_dummy_entry_t *entry;
+// H5X_DUMMY_LOG_DEBUG("Query returns %zu references", query_result.n_elem);
+// H5Q_QUEUE_FOREACH(entry, &query_result, entry)
+// printf_ref(entry->ref);
+// }
+// H5X_DUMMY_LOG_DEBUG("###########################");
+
+ /* Fill result */
+ if (!H5Q_QUEUE_EMPTY(&query_result)) {
+ H5X_dummy_entry_t *entry;
+ int i = 0;
+
+ if (NULL == (ref_buf = H5MM_malloc(sizeof(href_t) * query_result.n_elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, FAIL, "can't allocate read buffer");
+
+ H5Q_QUEUE_FOREACH(entry, &query_result, entry) {
+ ref_buf[i] = H5Rcopy(entry->ref);
+ i++;
+ }
+ }
+
+ *ref_count = query_result.n_elem;
+ *refs = ref_buf;
+
+done:
+ if (FAIL == H5X__dummy_metadata_remove_entries(&query_result))
+ HDONE_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to remove entries");
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X_dummy_query() */
+
+static herr_t
+H5X__dummy_metadata_query(H5X_dummy_metadata_t *metadata, hid_t query_id,
+ H5X_dummy_head_t *result)
+{
+ H5Q_type_t query_type;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (FAIL == H5Qget_type(query_id, &query_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+
+ if (query_type != H5Q_TYPE_MISC) {
+ if (FAIL == H5X__dummy_metadata_query_singleton(metadata, query_id, result))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to compare query");
+ } else {
+ H5Q_combine_op_t combine_op;
+ hid_t sub_query1_id, sub_query2_id;
+ H5X_dummy_head_t result1 = H5Q_QUEUE_HEAD_INITIALIZER(result1);
+ H5X_dummy_head_t result2 = H5Q_QUEUE_HEAD_INITIALIZER(result2);
+
+ if (FAIL == H5Qget_combine_op(query_id, &combine_op))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get combine op");
+ if (FAIL == H5Qget_components(query_id, &sub_query1_id, &sub_query2_id))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get components");
+
+ if (FAIL == H5X__dummy_metadata_query(metadata, sub_query1_id, &result1))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query");
+
+// H5X_DUMMY_LOG_DEBUG("###########################");
+// if (!H5Q_QUEUE_EMPTY(&result1)) {
+// H5X_dummy_entry_t *entry;
+// H5X_DUMMY_LOG_DEBUG("Query returns %zu references", result1.n_elem);
+// H5Q_QUEUE_FOREACH(entry, &result1, entry)
+// printf_ref(entry->ref);
+// }
+// H5X_DUMMY_LOG_DEBUG("###########################");
+
+ if (FAIL == H5X__dummy_metadata_query(metadata, sub_query2_id, &result2))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query");
+
+// H5X_DUMMY_LOG_DEBUG("###########################");
+// if (!H5Q_QUEUE_EMPTY(&result2)) {
+// H5X_dummy_entry_t *entry;
+// H5X_DUMMY_LOG_DEBUG("Query returns %zu references", result2.n_elem);
+// H5Q_QUEUE_FOREACH(entry, &result2, entry)
+// printf_ref(entry->ref);
+// }
+// H5X_DUMMY_LOG_DEBUG("###########################");
+
+ if (FAIL == H5X__dummy_metadata_query_combine(combine_op, &result1, &result2, result))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTMERGE, FAIL, "unable to merge results");
+
+// H5X_DUMMY_LOG_DEBUG("###########################");
+// if (!H5Q_QUEUE_EMPTY(result)) {
+// H5X_dummy_entry_t *entry;
+// H5X_DUMMY_LOG_DEBUG("Query returns %zu references", result->n_elem);
+// H5Q_QUEUE_FOREACH(entry, result, entry)
+// printf_ref(entry->ref);
+// }
+// H5X_DUMMY_LOG_DEBUG("###########################");
+
+ if (FAIL == H5X__dummy_metadata_remove_entries(&result1))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to remove entries");
+ if (FAIL == H5X__dummy_metadata_remove_entries(&result2))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to remove entries");
+ if (FAIL == H5Qclose(sub_query1_id))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCLOSEOBJ, FAIL, "unable to close query");
+ if (FAIL == H5Qclose(sub_query2_id))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCLOSEOBJ, FAIL, "unable to close query");
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_query */
+
+static herr_t
+H5X__dummy_metadata_query_singleton(H5X_dummy_metadata_t *metadata,
+ hid_t query_id, H5X_dummy_head_t *result)
+{
+ H5X_dummy_entry_t *entry;
+ H5Q_type_t query_type;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (FAIL == H5Qget_type(query_id, &query_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+ switch (query_type) {
+ case H5Q_TYPE_LINK_NAME:
+ H5Q_QUEUE_FOREACH(entry, &metadata->link_names, entry) {
+ hbool_t apply_result = FALSE;
+ if (FAIL == H5Qapply_atom(query_id, &apply_result, entry->key.name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't compare link name");
+ if (!apply_result) continue;
+
+// H5X_DUMMY_LOG_DEBUG("Match link name: %s", (const char *) entry->key.name);
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ H5Q_QUEUE_FOREACH(entry, &metadata->attr_names, entry) {
+ hbool_t apply_result = FALSE;
+ if (FAIL == H5Qapply_atom(query_id, &apply_result, entry->key.name))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't compare attribute name");
+ if (!apply_result) continue;
+
+// H5X_DUMMY_LOG_DEBUG("Match attribute name: %s", (const char *) entry->key.name);
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ break;
+ case H5Q_TYPE_ATTR_VALUE:
+ H5Q_QUEUE_FOREACH(entry, &metadata->attr_values, entry) {
+ hbool_t apply_result = FALSE;
+ if (FAIL == H5Qapply_atom(query_id, &apply_result, entry->key.elem.type, entry->key.elem.value))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't compare attribute values");
+ if (!apply_result) continue;
+
+// H5X_DUMMY_LOG_DEBUG("Match attribute value: %d", *((int *) entry->key.elem.value));
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ break;
+ case H5Q_TYPE_DATA_ELEM:
+ case H5Q_TYPE_MISC:
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_query_singleton */
+
+static herr_t
+H5X__dummy_metadata_query_combine(H5Q_combine_op_t combine_op,
+ H5X_dummy_head_t *result1, H5X_dummy_head_t *result2, H5X_dummy_head_t *result)
+{
+ H5X_dummy_entry_t *entry1;
+ H5X_dummy_entry_t *entry2;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (combine_op == H5Q_COMBINE_AND) {
+ H5Q_QUEUE_FOREACH(entry1, result1, entry) {
+ H5R_type_t ref_type1 = H5Rget_type(entry1->ref);
+ H5Q_QUEUE_FOREACH(entry2, result2, entry) {
+ H5R_type_t ref_type2 = H5Rget_type(entry2->ref);
+
+ if (H5Requal(entry1->ref, entry2->ref)) {
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry1))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ else if (ref_type1 == H5R_EXT_ATTR && ref_type2 == H5R_EXT_OBJECT) {
+ char obj_name1[H5X_DUMMY_MAX_NAME_LEN];
+ char obj_name2[H5X_DUMMY_MAX_NAME_LEN];
+
+ /* Only combine if obj_names are equal */
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, entry1->ref,
+ obj_name1, H5X_DUMMY_MAX_NAME_LEN);
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, entry2->ref,
+ obj_name2, H5X_DUMMY_MAX_NAME_LEN);
+ if (0 == HDstrcmp(obj_name1, obj_name2))
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry2))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ else if (ref_type1 == H5R_EXT_OBJECT && ref_type2 == H5R_EXT_ATTR) {
+ char obj_name1[H5X_DUMMY_MAX_NAME_LEN];
+ char obj_name2[H5X_DUMMY_MAX_NAME_LEN];
+
+ /* Only combine if obj_names are equal */
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, entry1->ref,
+ obj_name1, H5X_DUMMY_MAX_NAME_LEN);
+ H5R__get_obj_name(NULL, H5P_DEFAULT, H5P_DEFAULT, entry2->ref,
+ obj_name2, H5X_DUMMY_MAX_NAME_LEN);
+ if (0 == HDstrcmp(obj_name1, obj_name2))
+ if (FAIL == H5X__dummy_metadata_add_entry(result, entry1))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTMERGE, FAIL, "unable to add result");
+ }
+ }
+ }
+ } else if (combine_op == H5Q_COMBINE_OR) {
+ /* TODO might want to remove eventual duplicates */
+ H5Q_QUEUE_CONCAT(result, result1);
+ H5Q_QUEUE_CONCAT(result, result2);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__dummy_metadata_query_combine */
diff --git a/src/H5Xpkg.h b/src/H5Xpkg.h
index d647e6f..7cb9bf5 100644
--- a/src/H5Xpkg.h
+++ b/src/H5Xpkg.h
@@ -41,4 +41,9 @@ H5_DLLVAR const H5X_class_t H5X_ALACRITY[1];
H5_DLLVAR const H5X_class_t H5X_FASTBIT[1];
#endif
+/*
+ * Dummy plugin meta
+ */
+H5_DLLVAR const H5X_class_t H5X_META_DUMMY[1];
+
#endif /* _H5Xpkg_H */
diff --git a/src/H5Xprivate.h b/src/H5Xprivate.h
index ad8966d..598ef6d 100644
--- a/src/H5Xprivate.h
+++ b/src/H5Xprivate.h
@@ -53,12 +53,12 @@ H5_DLL H5X_class_t *H5X_registered(unsigned plugin_id);
H5_DLL herr_t H5X_register(const H5X_class_t *index_plugin);
H5_DLL herr_t H5X_unregister(unsigned plugin_id);
-H5_DLL herr_t H5X_create(hid_t dset_id, unsigned plugin_id, hid_t xcpl_id);
-H5_DLL herr_t H5X_remove(hid_t dset_id, unsigned plugin_id);
-H5_DLL herr_t H5X_can_create(hid_t dset_id, hid_t dcpl_id);
+H5_DLL herr_t H5X_create(hid_t loc_id, unsigned plugin_id, hid_t xcpl_id);
+H5_DLL herr_t H5X_remove(hid_t loc_id, unsigned plugin_id);
+H5_DLL herr_t H5X_can_create_data(hid_t dset_id, hid_t dcpl_id);
-H5_DLL herr_t H5X_get_count(hid_t dset_id, hsize_t *idx_count);
+H5_DLL herr_t H5X_get_count(hid_t loc_id, hsize_t *idx_count);
-H5_DLL herr_t H5X_get_size(hid_t dset_id, hsize_t *idx_size);
+H5_DLL herr_t H5X_get_size(hid_t loc_id, hsize_t *idx_size);
#endif /* _H5Xprivate_H */
diff --git a/src/H5Xpublic.h b/src/H5Xpublic.h
index 28dad66..0636b05 100644
--- a/src/H5Xpublic.h
+++ b/src/H5Xpublic.h
@@ -32,16 +32,18 @@
#define H5X_CLASS_T_VERS (1)
/* Plugin IDs */
-#define H5X_PLUGIN_ERROR (-1) /* no plugin */
-#define H5X_PLUGIN_NONE 0 /* reserved indefinitely */
-#define H5X_PLUGIN_DUMMY 1 /* dummy */
-#define H5X_PLUGIN_FASTBIT 2 /* fastbit */
-#define H5X_PLUGIN_ALACRITY 3 /* alacrity */
+#define H5X_PLUGIN_ERROR (-1) /* no plugin */
+#define H5X_PLUGIN_NONE 0 /* reserved indefinitely */
+#define H5X_PLUGIN_DUMMY 1 /* dummy */
+#define H5X_PLUGIN_FASTBIT 2 /* fastbit */
+#define H5X_PLUGIN_ALACRITY 3 /* alacrity */
-#define H5X_PLUGIN_RESERVED 64 /* plugin ids below this value reserved */
+#define H5X_PLUGIN_META_DUMMY 4 /* metadata dummy */
-#define H5X_PLUGIN_MAX 256 /* maximum plugin id */
-#define H5X_MAX_NPLUGINS 16 /* Maximum number of plugins allowed in a pipeline */
+#define H5X_PLUGIN_RESERVED 64 /* plugin ids below this value reserved */
+
+#define H5X_PLUGIN_MAX 256 /* maximum plugin id */
+#define H5X_MAX_NPLUGINS 16 /* Maximum number of plugins allowed in a pipeline */
/*******************/
/* Public Typedefs */