summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJerome Soumagne <jsoumagne@hdfgroup.org>2016-06-13 20:24:23 (GMT)
committerJerome Soumagne <jsoumagne@hdfgroup.org>2016-11-29 23:42:33 (GMT)
commitf3da9b2a1952cba4484647aaaeb153994f474602 (patch)
tree1d6d2980623860da59b8fdf8e787115b80c98a17 /src
parenta4b81fe620b8ecf7e022544b00332e825ca33db0 (diff)
downloadhdf5-f3da9b2a1952cba4484647aaaeb153994f474602.zip
hdf5-f3da9b2a1952cba4484647aaaeb153994f474602.tar.gz
hdf5-f3da9b2a1952cba4484647aaaeb153994f474602.tar.bz2
Add support for db_join() in H5Xmeta_db
Diffstat (limited to 'src')
-rw-r--r--src/H5Xmeta_db.c1128
1 files changed, 847 insertions, 281 deletions
diff --git a/src/H5Xmeta_db.c b/src/H5Xmeta_db.c
index d0c19d8..e543a43 100644
--- a/src/H5Xmeta_db.c
+++ b/src/H5Xmeta_db.c
@@ -42,7 +42,7 @@
/****************/
/* Local Macros */
/****************/
-#define H5X_DB_DEBUG
+//#define H5X_DB_DEBUG
#ifdef H5X_DB_DEBUG
#define H5X_DB_LOG_DEBUG(...) do { \
@@ -139,13 +139,23 @@ struct { \
#define H5Q_QUEUE_FIRST(head) ((head)->stqh_first)
#define H5Q_QUEUE_NEXT(elm, field) ((elm)->field.stqe_next)
-#define H5X_DB_METADATA_TYPES 3
+//#define H5X_DB_METADATA_TYPES 3
+#define H5X_DB_NPRIMARIES 2
+#define H5X_DB_NSECONDARIES 4
#define H5X_DB_MAX_NAME_LEN (64 * 1024)
+#define H5X_DB_OBJ_REFS_SUFFIX "__obj_refs.db"
#define H5X_DB_LINK_NAMES_SUFFIX "__link_names.db"
+#define H5X_DB_ATTR_REFS_SUFFIX "__attr_refs.db"
#define H5X_DB_ATTR_NAMES_SUFFIX "__attr_names.db"
+#define H5X_DB_ATTR_LNAMES_SUFFIX "__attr_lnames.db"
#define H5X_DB_ATTR_VALUES_SUFFIX "__attr_values.db"
+#define H5X_DB_PAGE_SIZE 4096 /* Should match filesystem block size */
+#define H5X_DB_CACHE_SIZE (1024 * 1024)
+
+#define H5X_DB_USE_JOIN
+
/******************/
/* Local Typedefs */
/******************/
@@ -153,22 +163,50 @@ struct { \
typedef struct H5X_db_entry_t H5X_db_entry_t;
struct H5X_db_entry_t {
- H5Q_type_t type; /* Query type */
href_t ref; /* External reference */
H5Q_QUEUE_ENTRY(H5X_db_entry_t) entry;
};
typedef H5Q_QUEUE_HEAD(H5X_db_head_t, H5X_db_entry_t) H5X_db_head_t;
+typedef struct H5X_db_query_entry_t H5X_db_query_entry_t;
+
+struct H5X_db_query_entry_t {
+ H5Q_type_t type; /* Query type */
+ hid_t query_id; /* Query ID */
+ H5Q_QUEUE_ENTRY(H5X_db_query_entry_t) entry;
+};
+
+typedef H5Q_QUEUE_HEAD(H5X_db_query_head_t, H5X_db_query_entry_t) H5X_db_query_head_t;
+
typedef struct H5X_db_t {
- char *link_names_file;
- char *attr_names_file;
- char *attr_values_file;
- DB *link_names_db;
- DB *attr_names_db;
- DB *attr_values_db;
+ char *obj_refs_file; /* Database filename for objects */
+ char *link_names_file; /* Database filename for link names */
+ char *attr_refs_file; /* Database filename for attributes */
+ char *attr_names_file; /* Database filename for attribute names */
+ char *attr_link_names_file; /* Database filename for attribute link names */
+ char *attr_values_file; /* Database filename for attribute values */
+ DB *obj_refs_db; /* Primary database for objects */
+ DB *link_names_db; /* Secondary database for link names */
+ DB *attr_refs_db; /* Primary database for attributes */
+ DB *attr_names_db; /* Secondary database for attribute names */
+ DB *attr_link_names_db; /* Secondary database for attribute link names */
+ DB *attr_values_db; /* Secondary database for attribute values */
} H5X_db_t;
+typedef struct H5X_db_obj_t {
+ const char *name;
+} H5X_db_obj_t;
+
+typedef struct H5X_db_attr_t {
+ const char *name;
+ const char *link_name;
+ void *elmts;
+ size_t elmt_size;
+ size_t nelmts;
+// href_t obj_ref;
+} H5X_db_attr_t;
+
typedef struct {
const char *filename;
const char *loc_name;
@@ -186,23 +224,31 @@ typedef struct {
static herr_t H5X__db_index(hid_t oid, const char *name, const H5O_info_t *oinfo,
void *udata);
-static herr_t H5X__db_index_link_name(H5X_db_t *db, hid_t loc_id,
+static herr_t H5X__db_index_obj(H5X_db_t *db, hid_t loc_id,
const char *name, const H5O_info_t *oinfo);
static herr_t H5X__db_index_attrs(H5X_db_t *db, hid_t loc_id,
const char *name);
static herr_t H5X__db_index_attr(hid_t loc_id, const char *attr_name,
const H5A_info_t H5_ATTR_UNUSED *ainfo, void *udata);
-static herr_t H5X__db_index_attr_name(const char *attr_name, void *udata);
-static herr_t H5X__db_index_attr_value(hid_t loc_id, const char *attr_name,
- void *udata);
-static herr_t H5X__db_index_attr_value_iterate(void *elem, hid_t type_id,
- unsigned ndim, const hsize_t *point, void *udata);
-static herr_t H5X__db_put(H5X_db_t *db, href_t ref, H5Q_type_t type, ...);
+//static herr_t H5X__db_index_attr_value_iterate(void *elem, hid_t type_id,
+// unsigned ndim, const hsize_t *point, void *udata);
+static herr_t H5X__db_insert_obj(H5X_db_t *db, href_t ref, H5X_db_obj_t *obj);
+static herr_t H5X__db_insert_attr(H5X_db_t *db, href_t ref, H5X_db_attr_t *attr);
+#ifndef H5X_DB_USE_JOIN
static herr_t H5X__db_push_entry(H5X_db_head_t *head,
H5X_db_entry_t *entry);
+#endif
static herr_t H5X__db_remove_entries(H5X_db_head_t *head);
static herr_t H5X__db_gen_file_names(H5X_db_t *db, hid_t loc_id);
static herr_t H5X__db_free_file_names(H5X_db_t *db);
+static int H5X__db_get_link_name(DB *sdbp, const DBT *pkey, const DBT *pdata,
+ DBT *skey);
+static int H5X__db_get_attr_name(DB *sdbp, const DBT *pkey, const DBT *pdata,
+ DBT *skey);
+static int H5X__db_get_attr_link_name(DB *sdbp, const DBT *pkey,
+ const DBT *pdata, DBT *skey);
+static int H5X__db_get_attr_value(DB *sdbp, const DBT *pkey, const DBT *pdata,
+ DBT *skey);
static herr_t H5X__db_create_tables(H5X_db_t *db, hbool_t open, unsigned flags);
static herr_t H5X__db_close_tables(H5X_db_t *db);
static herr_t H5X__db_remove_tables(H5X_db_t *db);
@@ -215,8 +261,13 @@ static herr_t H5X__db_query_components(H5X_db_t *db, hid_t query_id,
H5X_db_head_t *result);
static herr_t H5X__db_query_singleton(H5X_db_t *db, hid_t query_id,
H5X_db_head_t *result);
+#ifndef H5X_DB_USE_JOIN
static herr_t H5X__db_query_combine(H5Q_combine_op_t combine_op,
H5X_db_head_t *result1, H5X_db_head_t *result2, H5X_db_head_t *result);
+#else
+static herr_t H5X__db_query_combine(H5X_db_t *db, hid_t query_id,
+ H5X_db_head_t *result);
+#endif
static void *H5X__db_create(hid_t loc_id, hid_t xcpl_id, hid_t xapl_id,
size_t *metadata_size, void **metadata);
@@ -294,7 +345,7 @@ H5X__db_index(hid_t oid, const char *name, const H5O_info_t *oinfo, void *udata)
HDassert(db);
/* Index link names */
- if (FAIL == H5X__db_index_link_name(db, oid, name, oinfo))
+ if (FAIL == H5X__db_index_obj(db, oid, name, oinfo))
HGOTO_ERROR(H5E_INDEX, H5E_CANTAPPEND, FAIL, "can't add link name");
/* Index attribute names/values */
@@ -306,9 +357,10 @@ done:
} /* end H5X__db_index */
static herr_t
-H5X__db_index_link_name(H5X_db_t *db, hid_t loc_id, const char *name,
+H5X__db_index_obj(H5X_db_t *db, hid_t loc_id, const char *name,
const H5O_info_t *oinfo)
{
+ H5X_db_obj_t db_obj;
href_t ref = NULL;
const char *link_name = NULL;
const char *trimmed_path = NULL;
@@ -334,14 +386,56 @@ H5X__db_index_link_name(H5X_db_t *db, hid_t loc_id, const char *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__db_put(db, ref, H5Q_TYPE_LINK_NAME, link_name))
+
+ db_obj.name = link_name;
+ if (FAIL == H5X__db_insert_obj(db, ref, &db_obj))
HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
done:
if (ref && FAIL == H5Rdestroy(ref))
HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy reference");
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5X__db_index_link_name */
+} /* end H5X__db_index_obj */
+
+static herr_t
+H5X__db_insert_obj(H5X_db_t *db, href_t ref, H5X_db_obj_t *obj)
+{
+ DBT key; /* The key to dbcp->put() */
+ DBT data; /* The data to dbcp->put() */
+ size_t ref_buf_size;
+ void *ref_buf = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+ int db_ret;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(db);
+ HDassert(ref);
+
+ /* Initialize key/data */
+ HDmemset(&key, 0, sizeof(DBT));
+ HDmemset(&data, 0, sizeof(DBT));
+
+ if (H5R_encode(ref, NULL, &ref_buf_size) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
+ if (NULL == (ref_buf = H5MM_malloc(ref_buf_size)))
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate buffer for encoding reference");
+ if (H5R_encode(ref, ref_buf, &ref_buf_size) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
+
+ key.data = ref_buf;
+ key.size = (u_int32_t)ref_buf_size;
+ data.data = obj;
+ data.size = (u_int32_t)(HDstrlen(obj->name) + 1);
+
+ if ((db_ret = db->obj_refs_db->put(db->obj_refs_db, NULL, &key, &data, 0)) != 0) {
+ db->obj_refs_db->err(db->obj_refs_db, db_ret, "DB->put");
+ }
+
+done:
+ H5MM_free(ref_buf);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__db_insert_obj */
static herr_t
H5X__db_index_attrs(H5X_db_t *db, hid_t loc_id, const char *name)
@@ -387,50 +481,6 @@ static herr_t
H5X__db_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__db_index_attr_name(attr_name, udata))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "can't apply attr name query to object");
-
- if (FAIL == H5X__db_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__db_index_attr */
-
-static herr_t
-H5X__db_index_attr_name(const char *attr_name, void *udata)
-{
- H5X_db_index_attr_arg_t *args = (H5X_db_index_attr_arg_t *) udata;
- href_t ref = NULL;
- 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_CANTCREATE, FAIL, "can't create attribute reference");
- if (FAIL == H5X__db_put(args->db, ref, H5Q_TYPE_ATTR_NAME, attr_name))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
-
-done:
- if (ref && FAIL == H5Rdestroy(ref))
- HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy reference");
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5X__db_index_attr_name */
-
-static herr_t
-H5X__db_index_attr_value(hid_t loc_id, const char *attr_name, void *udata)
-{
H5X_db_index_attr_arg_t *args = (H5X_db_index_attr_arg_t *) udata;
void *buf = NULL;
size_t buf_size;
@@ -438,13 +488,16 @@ H5X__db_index_attr_value(hid_t loc_id, const char *attr_name, void *udata)
hid_t type_id = FAIL;
hid_t space_id = FAIL;
size_t nelmts, elmt_size;
- H5X_db_index_attr_elem_arg_t iter_args;
+ href_t ref = NULL;
+ H5X_db_attr_t db_attr;
+ const char *link_name = NULL;
+ const char *trimmed_path = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(attr_name);
- HDassert(args);
+ HDassert(udata);
/* Open attribute */
if (FAIL == (attr_id = H5Aopen(loc_id, attr_name, H5P_DEFAULT)))
@@ -469,55 +522,71 @@ H5X__db_index_attr_value(hid_t loc_id, const char *attr_name, void *udata)
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;
+ /* Keep attribute reference */
+ if (NULL == (ref = H5R_create_ext_attr(args->filename, args->loc_name, attr_name)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create attribute reference");
+
+ trimmed_path = HDstrrchr(args->loc_name, '/');
+ link_name = (trimmed_path) ? ++trimmed_path : args->loc_name;
+
+ db_attr.name = attr_name;
+ db_attr.link_name = link_name;
+ db_attr.elmt_size = elmt_size;
+ db_attr.elmts = buf;
+ db_attr.nelmts = nelmts;
+ // if (FAIL == (native_type_id = 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(native_type_id)))
+ // HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size");
+
+ if (FAIL == H5X__db_insert_attr(args->db, ref, &db_attr))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+// H5X_db_index_attr_elem_arg_t iter_args;
+ // 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__db_index_attr_value_iterate, &iter_args))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "unable to compare attribute elements");
+// if (FAIL == H5Diterate(buf, type_id, space_id, H5X__db_index_attr_value_iterate, &iter_args))
+// HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "unable to compare attribute elements");
done:
+ if (ref && FAIL == H5Rdestroy(ref))
+ HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy reference");
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__db_index_attr_value */
-
-static herr_t
-H5X__db_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_db_index_attr_elem_arg_t *args = (H5X_db_index_attr_elem_arg_t *) udata;
- href_t ref = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT
-
- HDassert(elem);
- HDassert(args);
+} /* end H5X__db_index_attr */
- /* 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_CANTCREATE, FAIL, "can't create attribute reference");
- if (FAIL == H5X__db_put(args->attr_args->db, ref, H5Q_TYPE_ATTR_VALUE, type_id, elem))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
-
-done:
- if (ref && FAIL == H5Rdestroy(ref))
- HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy reference");
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5X__db_index_attr_value_iterate */
+//static herr_t
+//H5X__db_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_db_index_attr_elem_arg_t *args = (H5X_db_index_attr_elem_arg_t *) udata;
+// herr_t ret_value = SUCCEED; /* Return value */
+//
+// FUNC_ENTER_NOAPI_NOINIT
+//
+// HDassert(elem);
+// HDassert(args);
+//
+// /* Keep attribute reference */
+//
+//
+//done:
+//
+// FUNC_LEAVE_NOAPI(ret_value)
+//} /* end H5X__db_index_attr_value_iterate */
static herr_t
-H5X__db_put(H5X_db_t *db, href_t ref, H5Q_type_t type, ...)
+H5X__db_insert_attr(H5X_db_t *db, href_t ref, H5X_db_attr_t *attr)
{
- va_list ap;
DBT key; /* The key to dbcp->put() */
DBT data; /* The data to dbcp->put() */
- size_t buf_size;
- void *buf = NULL;
+ size_t ref_buf_size;
+ void *ref_buf = NULL;
herr_t ret_value = SUCCEED; /* Return value */
int db_ret;
@@ -526,105 +595,150 @@ H5X__db_put(H5X_db_t *db, href_t ref, H5Q_type_t type, ...)
HDassert(db);
HDassert(ref);
- va_start(ap, type);
-
/* Initialize key/data */
HDmemset(&key, 0, sizeof(DBT));
HDmemset(&data, 0, sizeof(DBT));
- if (H5R_encode(ref, NULL, &buf_size) < 0)
+ if (H5R_encode(ref, NULL, &ref_buf_size) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
- if (NULL == (buf = H5MM_malloc(buf_size)))
+ if (NULL == (ref_buf = H5MM_malloc(ref_buf_size)))
HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate buffer for encoding reference");
- if (H5R_encode(ref, buf, &buf_size) < 0)
+ if (H5R_encode(ref, ref_buf, &ref_buf_size) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
- switch (type) {
- case H5Q_TYPE_ATTR_VALUE:
- {
- hid_t datatype_id;
- hid_t native_type_id;
- size_t datatype_size;
- const void *value;
- void *encoded_value = NULL;
-
- /* Get arguments */
- datatype_id = va_arg(ap, hid_t);
- value = va_arg(ap, const void *);
-
- HDassert(datatype_id != FAIL);
- HDassert(value);
-
- if (FAIL == (native_type_id = 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(native_type_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size");
- if (NULL == (encoded_value = H5MM_malloc(datatype_size)))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer");
- HDmemcpy(encoded_value, value, datatype_size);
-
- key.data = encoded_value;
- key.size = (u_int32_t)datatype_size;
- data.data = buf;
- data.size = (u_int32_t)buf_size;
-
- if ((db_ret = db->attr_values_db->put(db->attr_values_db, NULL, &key, &data, 0)) != 0) {
- db->attr_values_db->err(db->attr_values_db, db_ret, "DB->put");
- }
- H5MM_free(encoded_value);
- }
- break;
- case H5Q_TYPE_ATTR_NAME:
- {
- char *attr_name;
-
- /* Get arguments */
- attr_name = va_arg(ap, char *);
-
- HDassert(attr_name);
-
- key.data = attr_name;
- key.size = (u_int32_t)(HDstrlen(attr_name) + 1);
- data.data = buf;
- data.size = (u_int32_t)buf_size;
-
- if ((db_ret = db->attr_names_db->put(db->attr_names_db, NULL, &key, &data, 0)) != 0) {
- db->attr_names_db->err(db->attr_names_db, db_ret, "DB->put");
- }
- }
- break;
- case H5Q_TYPE_LINK_NAME:
- {
- char *link_name;
-
- /* Get arguments */
- link_name = va_arg(ap, char *);
+ key.data = ref_buf;
+ key.size = (u_int32_t)ref_buf_size;
- HDassert(link_name);
+ data.data = attr;
+ data.size = (u_int32_t)(HDstrlen(attr->name) + 1
+ + HDstrlen(attr->link_name) + 1 + attr->nelmts * attr->elmt_size
+ + sizeof(attr->elmt_size) + sizeof(attr->nelmts));
- key.data = link_name;
- key.size = (u_int32_t)(HDstrlen(link_name) + 1);
- data.data = buf;
- data.size = (u_int32_t)buf_size;
-
- if ((db_ret = db->link_names_db->put(db->link_names_db, NULL, &key, &data, 0)) != 0) {
- db->link_names_db->err(db->link_names_db, db_ret, "DB->put");
- }
- }
- break;
- case H5Q_TYPE_MISC:
- default:
- HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
- break;
+ if ((db_ret = db->attr_refs_db->put(db->attr_refs_db, NULL, &key, &data, 0)) != 0) {
+ db->attr_refs_db->err(db->attr_refs_db, db_ret, "DB->put");
}
done:
- va_end(ap);
-
- H5MM_free(buf);
+ H5MM_free(ref_buf);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5X__db_put */
-
+} /* end H5X__db_insert_attr */
+
+//static herr_t
+//H5X__db_put(H5X_db_t *db, href_t ref, H5Q_type_t type, ...)
+//{
+// va_list ap;
+// DBT key; /* The key to dbcp->put() */
+// DBT data; /* The data to dbcp->put() */
+// size_t buf_size;
+// void *buf = NULL;
+// herr_t ret_value = SUCCEED; /* Return value */
+// int db_ret;
+//
+// FUNC_ENTER_NOAPI_NOINIT
+//
+// HDassert(db);
+// HDassert(ref);
+//
+// va_start(ap, type);
+//
+// /* Initialize key/data */
+// HDmemset(&key, 0, sizeof(DBT));
+// HDmemset(&data, 0, sizeof(DBT));
+//
+// if (H5R_encode(ref, NULL, &buf_size) < 0)
+// HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
+// if (NULL == (buf = H5MM_malloc(buf_size)))
+// HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate buffer for encoding reference");
+// if (H5R_encode(ref, buf, &buf_size) < 0)
+// HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't encode reference");
+//
+// switch (type) {
+// case H5Q_TYPE_ATTR_VALUE:
+// {
+// hid_t datatype_id;
+// hid_t native_type_id;
+// size_t datatype_size;
+// const void *value;
+// void *encoded_value = NULL;
+//
+// /* Get arguments */
+// datatype_id = va_arg(ap, hid_t);
+// value = va_arg(ap, const void *);
+//
+// HDassert(datatype_id != FAIL);
+// HDassert(value);
+//
+// if (FAIL == (native_type_id = 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(native_type_id)))
+// HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size");
+// if (NULL == (encoded_value = H5MM_malloc(datatype_size)))
+// HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer");
+// HDmemcpy(encoded_value, value, datatype_size);
+//
+// key.data = encoded_value;
+// key.size = (u_int32_t)datatype_size;
+// data.data = buf;
+// data.size = (u_int32_t)buf_size;
+//
+// if ((db_ret = db->attr_values_db->put(db->attr_values_db, NULL, &key, &data, 0)) != 0) {
+// db->attr_values_db->err(db->attr_values_db, db_ret, "DB->put");
+// }
+// H5MM_free(encoded_value);
+// }
+// break;
+// case H5Q_TYPE_ATTR_NAME:
+// {
+// char *attr_name;
+//
+// /* Get arguments */
+// attr_name = va_arg(ap, char *);
+//
+// HDassert(attr_name);
+//
+// key.data = attr_name;
+// key.size = (u_int32_t)(HDstrlen(attr_name) + 1);
+// data.data = buf;
+// data.size = (u_int32_t)buf_size;
+//
+// if ((db_ret = db->attr_names_db->put(db->attr_names_db, NULL, &key, &data, 0)) != 0) {
+// db->attr_names_db->err(db->attr_names_db, db_ret, "DB->put");
+// }
+// }
+// break;
+// case H5Q_TYPE_LINK_NAME:
+// {
+// char *link_name;
+//
+// /* Get arguments */
+// link_name = va_arg(ap, char *);
+//
+// HDassert(link_name);
+//
+// key.data = link_name;
+// key.size = (u_int32_t)(HDstrlen(link_name) + 1);
+// data.data = buf;
+// data.size = (u_int32_t)buf_size;
+//
+// if ((db_ret = db->link_names_db->put(db->link_names_db, NULL, &key, &data, 0)) != 0) {
+// db->link_names_db->err(db->link_names_db, db_ret, "DB->put");
+// }
+// }
+// break;
+// case H5Q_TYPE_MISC:
+// default:
+// HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+// break;
+// }
+//
+//done:
+// va_end(ap);
+//
+// H5MM_free(buf);
+// FUNC_LEAVE_NOAPI(ret_value)
+//} /* end H5X__db_put */
+
+#ifndef H5X_DB_USE_JOIN
static herr_t
H5X__db_push_entry(H5X_db_head_t *head, H5X_db_entry_t *entry)
{
@@ -638,13 +752,13 @@ H5X__db_push_entry(H5X_db_head_t *head, H5X_db_entry_t *entry)
if (NULL == (new_entry = (H5X_db_entry_t *) H5MM_malloc(sizeof(H5X_db_entry_t))))
HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry");
- new_entry->type = entry->type;
new_entry->ref = H5Rcopy(entry->ref);
H5Q_QUEUE_INSERT_TAIL(head, new_entry, entry);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_push_entry */
+#endif
static herr_t
H5X__db_remove_entries(H5X_db_head_t *head)
@@ -673,10 +787,14 @@ H5X__db_gen_file_names(H5X_db_t *db, hid_t loc_id)
char filename[H5X_DB_MAX_NAME_LEN];
ssize_t filename_len;
char *filename_prefix = NULL;
- char **db_filename_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_file,
- &db->attr_names_file, &db->attr_values_file };
- const char *db_filename_suffixes[H5X_DB_METADATA_TYPES] = { H5X_DB_LINK_NAMES_SUFFIX,
- H5X_DB_ATTR_NAMES_SUFFIX, H5X_DB_ATTR_VALUES_SUFFIX };
+ char **db_filename_ptrs[H5X_DB_NPRIMARIES] = { &db->obj_refs_file,
+ &db->attr_refs_file };
+ const char *db_filename_suffixes[H5X_DB_NPRIMARIES] = { H5X_DB_OBJ_REFS_SUFFIX,
+ H5X_DB_ATTR_REFS_SUFFIX };
+ char **sdb_filename_ptrs[H5X_DB_NSECONDARIES] = { &db->link_names_file,
+ &db->attr_names_file, &db->attr_link_names_file, &db->attr_values_file };
+ const char *sdb_filename_suffixes[H5X_DB_NSECONDARIES] = { H5X_DB_LINK_NAMES_SUFFIX,
+ H5X_DB_ATTR_NAMES_SUFFIX, H5X_DB_ATTR_LNAMES_SUFFIX, H5X_DB_ATTR_VALUES_SUFFIX };
herr_t ret_value = SUCCEED;
int i;
@@ -692,10 +810,10 @@ H5X__db_gen_file_names(H5X_db_t *db, hid_t loc_id)
if (!filename_prefix)
HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "invalid file name (no '.' delim)");
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+ /* Create file names for primaries */
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++) {
char *db_filename;
- /* Generate filename for link names */
if (NULL == (db_filename = (char *) H5MM_malloc(
HDstrlen(filename_prefix) + HDstrlen(db_filename_suffixes[i]) + 1)))
HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate db struct");
@@ -704,6 +822,18 @@ H5X__db_gen_file_names(H5X_db_t *db, hid_t loc_id)
*db_filename_ptrs[i] = db_filename;
}
+ /* Create file names for secondaries */
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
+ char *sdb_filename;
+
+ if (NULL == (sdb_filename = (char *) H5MM_malloc(
+ HDstrlen(filename_prefix) + HDstrlen(sdb_filename_suffixes[i]) + 1)))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate db struct");
+ HDstrcpy(sdb_filename, filename_prefix);
+ HDstrcat(sdb_filename, sdb_filename_suffixes[i]);
+ *sdb_filename_ptrs[i] = sdb_filename;
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_gen_file_names() */
@@ -711,8 +841,10 @@ done:
static herr_t
H5X__db_free_file_names(H5X_db_t *db)
{
- char **db_filename_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_file,
- &db->attr_names_file, &db->attr_values_file };
+ char **db_filename_ptrs[H5X_DB_NPRIMARIES] = { &db->obj_refs_file,
+ &db->attr_refs_file };
+ char **sdb_filename_ptrs[H5X_DB_NSECONDARIES] = { &db->link_names_file,
+ &db->attr_names_file, &db->attr_link_names_file, &db->attr_values_file };
herr_t ret_value = SUCCEED;
int i;
@@ -720,50 +852,224 @@ H5X__db_free_file_names(H5X_db_t *db)
HDassert(db);
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++)
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++)
*db_filename_ptrs[i] = H5MM_xfree(*db_filename_ptrs[i]);
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++)
+ *sdb_filename_ptrs[i] = H5MM_xfree(*sdb_filename_ptrs[i]);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_free_file_names() */
+static int
+H5X__db_get_link_name(DB H5_ATTR_UNUSED *sdbp, const DBT H5_ATTR_UNUSED *pkey,
+ const DBT *pdata, DBT *skey)
+{
+ H5X_db_obj_t *obj;
+
+ /* First, extract the structure contained in the primary's data */
+ obj = pdata->data;
+
+ /* Now set the secondary key's data to be the object name */
+ HDmemset(skey, 0, sizeof(DBT));
+ skey->data = obj->name;
+ skey->size = (u_int32_t)(HDstrlen(obj->name) + 1);
+ H5X_DB_LOG_DEBUG("Extracting link name: %s", (const char *)skey->data);
+
+ /* Return 0 to indicate that the record can be created/updated */
+ return 0;
+} /* H5X__db_get_link_name */
+
+static int
+H5X__db_get_attr_name(DB H5_ATTR_UNUSED *sdbp, const DBT H5_ATTR_UNUSED *pkey,
+ const DBT *pdata, DBT *skey)
+{
+ H5X_db_attr_t *attr;
+
+ /* First, extract the structure contained in the primary's data */
+ attr = pdata->data;
+
+ /* Now set the secondary key's data to be the attribute name */
+ HDmemset(skey, 0, sizeof(DBT));
+ skey->data = attr->name;
+ skey->size = (u_int32_t)(HDstrlen(attr->name) + 1);
+ H5X_DB_LOG_DEBUG("Extracting attr name: %s", (const char *)skey->data);
+
+ /* Return 0 to indicate that the record can be created/updated */
+ return 0;
+} /* H5X__db_get_attr_name */
+
+static int
+H5X__db_get_attr_link_name(DB H5_ATTR_UNUSED *sdbp, const DBT H5_ATTR_UNUSED *pkey,
+ const DBT *pdata, DBT *skey)
+{
+ H5X_db_attr_t *attr;
+
+ /* First, extract the structure contained in the primary's data */
+ attr = pdata->data;
+
+ /* Now set the secondary key's data to be the attribute name */
+ HDmemset(skey, 0, sizeof(DBT));
+ skey->data = attr->link_name;
+ skey->size = (u_int32_t)(HDstrlen(attr->link_name) + 1);
+ H5X_DB_LOG_DEBUG("Extracting attr link name: %s", (const char *)skey->data);
+
+ /* Return 0 to indicate that the record can be created/updated */
+ return 0;
+} /* H5X__db_get_attr_link_name */
+
+static int
+H5X__db_get_attr_value(DB H5_ATTR_UNUSED *sdbp, const DBT H5_ATTR_UNUSED *pkey,
+ const DBT *pdata, DBT *skey)
+{
+ H5X_db_attr_t *attr;
+
+ /* First, extract the structure contained in the primary's data */
+ attr = pdata->data;
+
+ /* Now set the secondary key's data to be the attribute value */
+ HDmemset(skey, 0, sizeof(DBT));
+ skey->data = attr->elmts;
+ skey->size = (u_int32_t)(attr->elmt_size);
+ H5X_DB_LOG_DEBUG("Extracting attr value: %d", *((int*)skey->data));
+
+ /* Return 0 to indicate that the record can be created/updated */
+ return 0;
+} /* H5X__db_get_attr_value */
+
static herr_t
H5X__db_create_tables(H5X_db_t *db, hbool_t open, unsigned flags)
{
herr_t ret_value = SUCCEED; /* Return value */
- DB **db_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_db,
- &db->attr_names_db, &db->attr_values_db };
- const char *db_filenames[H5X_DB_METADATA_TYPES] = { db->link_names_file,
- db->attr_names_file, db->attr_values_file };
int db_ret;
- int i;
FUNC_ENTER_NOAPI_NOINIT
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
- DB *dbp;
+ /* Create primary database for objects */
+ if ((db_ret = db_create(&db->obj_refs_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if (open) {
+ if ((db_ret = db->obj_refs_db->set_pagesize(db->obj_refs_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->obj_refs_db->err(db->obj_refs_db, db_ret, "set_pagesize");
+ if ((db_ret = db->obj_refs_db->set_cachesize(db->obj_refs_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->obj_refs_db->err(db->obj_refs_db, db_ret, "set_cachesize");
+
+ /* Open and make it a DB_BTREE */
+ if ((db_ret = db->obj_refs_db->open(db->obj_refs_db, NULL,
+ db->obj_refs_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->obj_refs_db->err(db->obj_refs_db, db_ret, "open: %s",
+ db->obj_refs_file);
+ }
+ }
- /* Create the database handles */
- if ((db_ret = db_create(&dbp, NULL, 0)) != 0)
- HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
- "can't create database: db_create: %s", db_strerror(db_ret));
- *db_ptrs[i] = dbp;
+ /* Create primary database for attributes */
+ if ((db_ret = db_create(&db->attr_refs_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if (open) {
+ if ((db_ret = db->attr_refs_db->set_pagesize(db->attr_refs_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->attr_refs_db->err(db->attr_refs_db, db_ret, "set_pagesize");
+ if ((db_ret = db->attr_refs_db->set_cachesize(db->attr_refs_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->attr_refs_db->err(db->attr_refs_db, db_ret, "set_cachesize");
+
+ /* Open and make it a DB_BTREE */
+ if ((db_ret = db->attr_refs_db->open(db->attr_refs_db, NULL,
+ db->attr_refs_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->attr_refs_db->err(db->attr_refs_db, db_ret, "open: %s",
+ db->attr_refs_file);
+ }
+ }
- if (open) {
- /* Configure the database to use 1KB page sizes */
- if ((db_ret = dbp->set_pagesize(dbp, 1024)) != 0) {
- dbp->err(dbp, db_ret, "set_pagesize");
- }
+ /* Create secondary database for objects */
+ if ((db_ret = db_create(&db->link_names_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if (open) {
+ /* Allow duplicates */
+ if ((db_ret = db->link_names_db->set_flags(db->link_names_db, DB_DUP)) != 0)
+ db->link_names_db->err(db->link_names_db, db_ret, "set_flags: DB_DUP");
+ if ((db_ret = db->link_names_db->set_pagesize(db->link_names_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->link_names_db->err(db->link_names_db, db_ret, "set_pagesize");
+ if ((db_ret = db->link_names_db->set_cachesize(db->link_names_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->link_names_db->err(db->link_names_db, db_ret, "set_cachesize");
+
+ /* Open and make it a DB_BTREE */
+ if ((db_ret = db->link_names_db->open(db->link_names_db, NULL,
+ db->link_names_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->link_names_db->err(db->link_names_db, db_ret, "open: %s",
+ db->link_names_file);
+ }
- /* Allow duplicates */
- if ((db_ret = dbp->set_flags(dbp, DB_DUP)) != 0)
- dbp->err(dbp, db_ret, "set_flags: DB_DUP");
+ /* Now associate the secondary to the primary */
+ if ((db_ret = db->link_names_db->associate(db->obj_refs_db, NULL,
+ db->link_names_db, H5X__db_get_link_name, 0) != 0))
+ db->link_names_db->err(db->link_names_db, db_ret, "associate: %s",
+ db_strerror(db_ret));
+ }
- /* Open and make it a DB_BTREE */
- if ((db_ret = dbp->open(dbp, NULL, db_filenames[i],
- NULL, DB_BTREE, flags, 0664)) != 0) {
- dbp->err(dbp, db_ret, "open: %s", db_filenames[i]);
- }
+ /* Create secondary database for attributes */
+ if ((db_ret = db_create(&db->attr_names_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if ((db_ret = db_create(&db->attr_link_names_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if ((db_ret = db_create(&db->attr_values_db, NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, FAIL,
+ "can't create database: db_create: %s", db_strerror(db_ret));
+ if (open) {
+ /* Allow duplicates */
+ if ((db_ret = db->attr_names_db->set_flags(db->attr_names_db, DB_DUP)) != 0)
+ db->attr_names_db->err(db->attr_names_db, db_ret, "set_flags: DB_DUP");
+ if ((db_ret = db->attr_link_names_db->set_flags(db->attr_link_names_db, DB_DUP)) != 0)
+ db->attr_link_names_db->err(db->attr_link_names_db, db_ret, "set_flags: DB_DUP");
+ if ((db_ret = db->attr_values_db->set_flags(db->attr_values_db, DB_DUP)) != 0)
+ db->attr_values_db->err(db->attr_values_db, db_ret, "set_flags: DB_DUP");
+
+ if ((db_ret = db->attr_names_db->set_pagesize(db->attr_names_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->attr_names_db->err(db->attr_names_db, db_ret, "set_pagesize");
+ if ((db_ret = db->attr_link_names_db->set_pagesize(db->attr_link_names_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->attr_link_names_db->err(db->attr_link_names_db, db_ret, "set_pagesize");
+ if ((db_ret = db->attr_values_db->set_pagesize(db->attr_values_db, H5X_DB_PAGE_SIZE)) != 0)
+ db->attr_values_db->err(db->attr_values_db, db_ret, "set_pagesize");
+
+ if ((db_ret = db->attr_names_db->set_cachesize(db->attr_names_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->attr_names_db->err(db->attr_names_db, db_ret, "set_pagesize");
+ if ((db_ret = db->attr_link_names_db->set_cachesize(db->attr_link_names_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->attr_link_names_db->err(db->attr_link_names_db, db_ret, "set_pagesize");
+ if ((db_ret = db->attr_values_db->set_cachesize(db->attr_values_db, 0, H5X_DB_CACHE_SIZE, 0)) != 0)
+ db->attr_values_db->err(db->attr_values_db, db_ret, "set_pagesize");
+
+ /* Open and make it a DB_BTREE */
+ if ((db_ret = db->attr_names_db->open(db->attr_names_db, NULL,
+ db->attr_names_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->attr_names_db->err(db->attr_names_db, db_ret, "open: %s",
+ db->attr_names_file);
+ }
+ if ((db_ret = db->attr_link_names_db->open(db->attr_link_names_db, NULL,
+ db->attr_link_names_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->attr_link_names_db->err(db->attr_link_names_db, db_ret, "open: %s",
+ db->attr_link_names_file);
}
+ if ((db_ret = db->attr_values_db->open(db->attr_values_db, NULL,
+ db->attr_values_file, NULL, DB_BTREE, flags, 0664)) != 0) {
+ db->attr_values_db->err(db->attr_values_db, db_ret, "open: %s",
+ db->attr_values_file);
+ }
+
+ /* Now associate the secondary to the primary */
+ if ((db_ret = db->attr_names_db->associate(db->attr_refs_db, NULL,
+ db->attr_names_db, H5X__db_get_attr_name, 0) != 0))
+ db->attr_names_db->err(db->attr_names_db, db_ret, "associate: %s",
+ db_strerror(db_ret));
+ if ((db_ret = db->attr_link_names_db->associate(db->attr_refs_db, NULL,
+ db->attr_link_names_db, H5X__db_get_attr_link_name, 0) != 0))
+ db->attr_link_names_db->err(db->attr_link_names_db, db_ret, "associate: %s",
+ db_strerror(db_ret));
+ if ((db_ret = db->attr_values_db->associate(db->attr_refs_db, NULL,
+ db->attr_values_db, H5X__db_get_attr_value, 0) != 0))
+ db->attr_values_db->err(db->attr_values_db, db_ret, "associate: %s",
+ db_strerror(db_ret));
}
done:
@@ -774,14 +1080,27 @@ static herr_t
H5X__db_close_tables(H5X_db_t *db)
{
herr_t ret_value = SUCCEED; /* Return value */
- DB **db_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_db,
- &db->attr_names_db, &db->attr_values_db };
+ DB **db_ptrs[H5X_DB_NPRIMARIES] = { &db->obj_refs_db,
+ &db->attr_refs_db };
+ DB **sdb_ptrs[H5X_DB_NSECONDARIES] = { &db->link_names_db,
+ &db->attr_names_db, &db->attr_link_names_db, &db->attr_values_db };
int db_ret;
int i;
FUNC_ENTER_NOAPI_NOINIT
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+ /* Close secondaries */
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
+ DB *sdbp = *sdb_ptrs[i];
+
+ if ((db_ret = sdbp->close(sdbp, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "DB->close: %s",
+ db_strerror(db_ret));
+ *sdb_ptrs[i] = NULL;
+ }
+
+ /* Close primaries */
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++) {
DB *dbp = *db_ptrs[i];
if ((db_ret = dbp->close(dbp, 0)) != 0)
@@ -798,22 +1117,40 @@ static herr_t
H5X__db_remove_tables(H5X_db_t *db)
{
herr_t ret_value = SUCCEED; /* Return value */
- DB **db_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_db,
- &db->attr_names_db, &db->attr_values_db };
- const char *db_filenames[H5X_DB_METADATA_TYPES] = { db->link_names_file,
- db->attr_names_file, db->attr_values_file };
+ DB **db_ptrs[H5X_DB_NPRIMARIES] = { &db->obj_refs_db,
+ &db->attr_refs_db };
+ DB **sdb_ptrs[H5X_DB_NSECONDARIES] = { &db->link_names_db,
+ &db->attr_names_db, &db->attr_link_names_db, &db->attr_values_db };
+ const char *db_filenames[H5X_DB_NPRIMARIES] = { db->obj_refs_file,
+ db->attr_refs_file };
+ const char *sdb_filenames[H5X_DB_NSECONDARIES] = { db->link_names_file,
+ db->attr_names_file, db->attr_link_names_file, db->attr_values_file };
int db_ret;
int i;
FUNC_ENTER_NOAPI_NOINIT
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+ /* Remove secondaries */
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
+ DB *sdbp = *sdb_ptrs[i];
+
+ /* Remove the database handles */
+ if ((db_ret = sdbp->remove(sdbp, sdb_filenames[i], NULL, 0)) != 0)
+ HGOTO_ERROR(H5E_INDEX, H5E_CANTREMOVE, FAIL,
+ "can't remove database %s: DB->remove: %s", sdb_filenames[i],
+ db_strerror(db_ret));
+ *sdb_ptrs[i] = NULL;
+ }
+
+ /* Remove primaries */
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++) {
DB *dbp = *db_ptrs[i];
/* Remove the database handles */
if ((db_ret = dbp->remove(dbp, db_filenames[i], NULL, 0)) != 0)
HGOTO_ERROR(H5E_INDEX, H5E_CANTREMOVE, FAIL,
- "can't remove database: DB->remove: %s", db_strerror(db_ret));
+ "can't remove database %s: DB->remove: %s", db_filenames[i],
+ db_strerror(db_ret));
*db_ptrs[i] = NULL;
}
@@ -824,35 +1161,40 @@ done:
static void
H5X__db_stat(H5X_db_t *db)
{
- const char *db_filenames[H5X_DB_METADATA_TYPES] = { db->link_names_file,
- db->attr_names_file, db->attr_values_file };
- DB *dbs[H5X_DB_METADATA_TYPES] = { db->link_names_db, db->attr_names_db,
- db->attr_values_db };
- const char *db_names[H5X_DB_METADATA_TYPES] = { "link names", "attr names",
- "attr values" };
+ const char *sdb_filenames[H5X_DB_NSECONDARIES] = { db->link_names_file,
+ db->attr_names_file, db->attr_link_names_file, db->attr_values_file };
+ DB *sdbs[H5X_DB_NSECONDARIES] = { db->link_names_db, db->attr_names_db,
+ db->attr_link_names_db, db->attr_values_db };
+#ifdef H5X_DB_DEBUG
+ const char *sdb_names[H5X_DB_NSECONDARIES] = { "link names", "attr names",
+ "attr link names", "attr values" };
+#endif
int i;
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+ /* Stat secondaries */
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
DB_BTREE_STAT *statp; /* The statistic pointer to record the total amount of record number. */
struct stat st;
int db_ret;
/* Flush the database to disk so that we get a valid file size */
- if ((db_ret = dbs[i]->sync(dbs[i], 0)) != 0) {
- dbs[i]->err(dbs[i], db_ret, "DB->sync");
+ if ((db_ret = sdbs[i]->sync(sdbs[i], 0)) != 0) {
+ sdbs[i]->err(sdbs[i], db_ret, "DB->sync");
}
/* Get the database statistics and print the total number of records. */
- if ((db_ret = dbs[i]->stat(dbs[i], NULL, &statp, 0)) != 0) {
- dbs[i]->err(dbs[i], db_ret, "DB->stat");
+ if ((db_ret = sdbs[i]->stat(sdbs[i], NULL, &statp, 0)) != 0) {
+ sdbs[i]->err(sdbs[i], db_ret, "DB->stat");
}
-// if ((db_ret = dbs[i]->stat_print(dbs[i], 0)) != 0) {
-// dbs[i]->err(dbs[i], db_ret, "DB->stat_print");
+// if ((db_ret = sdbs[i]->stat_print(sdbs[i], 0)) != 0) {
+// sdbs[i]->err(sdbs[i], db_ret, "DB->stat_print");
// }
- HDstat(db_filenames[i], &st);
+ HDstat(sdb_filenames[i], &st);
- H5X_DB_LOG_DEBUG("Database contains %lu records for %s", (u_long)statp->bt_ndata, db_names[i]);
- H5X_DB_LOG_DEBUG("Current database size on disk: %lf MB", (float)st.st_size / (float)(1024 * 1024));
+ H5X_DB_LOG_DEBUG("Database contains %lu records for %s",
+ (u_long)statp->bt_ndata, sdb_names[i]);
+ H5X_DB_LOG_DEBUG("Current database size on disk: %lf MB",
+ (float)st.st_size / (float)(1024 * 1024));
HDfree(statp);
}
@@ -862,8 +1204,10 @@ static herr_t
H5X__db_metadata_write(H5X_db_t *db, size_t *plugin_metadata_size,
void **plugin_metadata)
{
- const char *db_filenames[H5X_DB_METADATA_TYPES] = { db->link_names_file,
- db->attr_names_file, db->attr_values_file };
+ const char *db_filenames[H5X_DB_NPRIMARIES] = { db->obj_refs_file,
+ db->attr_refs_file };
+ const char *sdb_filenames[H5X_DB_NSECONDARIES] = { db->link_names_file,
+ db->attr_names_file, db->attr_link_names_file, db->attr_values_file };
herr_t ret_value = SUCCEED; /* Return value */
size_t buf_size = 0;
void *buf;
@@ -876,16 +1220,23 @@ H5X__db_metadata_write(H5X_db_t *db, size_t *plugin_metadata_size,
HDassert(plugin_metadata_size);
HDassert(plugin_metadata);
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++)
buf_size += HDstrlen(db_filenames[i]) + 1;
- }
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++)
+ buf_size += HDstrlen(sdb_filenames[i]) + 1;
+
if (NULL == (buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate plugin metadata");
buf_ptr = buf;
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++) {
HDstrcpy(buf_ptr, db_filenames[i]);
buf_ptr += HDstrlen(db_filenames[i]) + 1;
}
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
+ HDstrcpy(buf_ptr, sdb_filenames[i]);
+ buf_ptr += HDstrlen(sdb_filenames[i]) + 1;
+ }
*plugin_metadata = buf;
*plugin_metadata_size = buf_size;
@@ -898,8 +1249,10 @@ static herr_t
H5X__db_metadata_read(size_t H5_ATTR_UNUSED plugin_metadata_size,
void *plugin_metadata, H5X_db_t *db)
{
- char **db_filename_ptrs[H5X_DB_METADATA_TYPES] = { &db->link_names_file,
- &db->attr_names_file, &db->attr_values_file };
+ char **db_filename_ptrs[H5X_DB_NPRIMARIES] = { &db->obj_refs_file,
+ &db->attr_refs_file };
+ char **sdb_filename_ptrs[H5X_DB_NSECONDARIES] = { &db->link_names_file,
+ &db->attr_names_file, &db->attr_link_names_file, &db->attr_values_file };
herr_t ret_value = SUCCEED; /* Return value */
char *buf_ptr;
int i;
@@ -911,10 +1264,11 @@ H5X__db_metadata_read(size_t H5_ATTR_UNUSED plugin_metadata_size,
HDassert(plugin_metadata);
buf_ptr = plugin_metadata;
- for (i = 0; i < H5X_DB_METADATA_TYPES; i++) {
+
+ /* Get file names for primaries */
+ for (i = 0; i < H5X_DB_NPRIMARIES; i++) {
char *db_filename;
- /* Generate filename for link names */
if (NULL == (db_filename = (char *) H5MM_malloc(HDstrlen(buf_ptr) + 1)))
HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate db struct");
HDstrcpy(db_filename, buf_ptr);
@@ -922,6 +1276,17 @@ H5X__db_metadata_read(size_t H5_ATTR_UNUSED plugin_metadata_size,
*db_filename_ptrs[i] = db_filename;
}
+ /* Get file names for secondaries */
+ for (i = 0; i < H5X_DB_NSECONDARIES; i++) {
+ char *sdb_filename;
+
+ if (NULL == (sdb_filename = (char *) H5MM_malloc(HDstrlen(buf_ptr) + 1)))
+ HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate db struct");
+ HDstrcpy(sdb_filename, buf_ptr);
+ buf_ptr += HDstrlen(sdb_filename) + 1;
+ *sdb_filename_ptrs[i] = sdb_filename;
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_metadata_read */
@@ -957,6 +1322,8 @@ H5X__db_create(hid_t loc_id, hid_t H5_ATTR_UNUSED xcpl_id,
db->link_names_db = NULL;
db->attr_names_file = NULL;
db->attr_names_db = NULL;
+ db->attr_link_names_file = NULL;
+ db->attr_link_names_db = NULL;
db->attr_values_file = NULL;
db->attr_values_db = NULL;
@@ -1153,8 +1520,8 @@ H5X__db_insert_entry(void *idx_handle, hid_t obj_id, H5Q_type_t key_type,
/* Keep attribute reference */
if (NULL == (ref = H5R_create_ext_attr(file_name, loc_name, attr_name)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create attribute reference");
- if (FAIL == H5X__db_put(db, ref, H5Q_TYPE_ATTR_VALUE, key->value.type, key->value.value))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
+// if (FAIL == H5X__db_put(db, ref, H5Q_TYPE_ATTR_VALUE, key->value.type, key->value.value))
+// HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
}
break;
case H5Q_TYPE_ATTR_NAME:
@@ -1162,8 +1529,8 @@ H5X__db_insert_entry(void *idx_handle, hid_t obj_id, H5Q_type_t key_type,
/* Keep attribute reference */
if (NULL == (ref = H5R_create_ext_attr(file_name, loc_name, key->name)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create attribute reference");
- if (FAIL == H5X__db_put(db, ref, H5Q_TYPE_ATTR_NAME, key->name))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
+// if (FAIL == H5X__db_put(db, ref, H5Q_TYPE_ATTR_NAME, key->name))
+// HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view");
}
break;
case H5Q_TYPE_LINK_NAME:
@@ -1171,8 +1538,8 @@ H5X__db_insert_entry(void *idx_handle, hid_t obj_id, H5Q_type_t key_type,
/* 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__db_put(db, ref, H5Q_TYPE_LINK_NAME, key->name))
- HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view");
+// if (FAIL == H5X__db_put(db, 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:
@@ -1243,12 +1610,14 @@ H5X__db_query(void *idx_handle, hid_t query_id, hid_t H5_ATTR_UNUSED xxpl_id,
HGOTO_ERROR(H5E_INDEX, H5E_CANTCOMPARE, FAIL, "can't query metadata");
H5X_DB_LOG_DEBUG("###########################");
+#ifdef H5X_DB_DEBUG
if (!H5Q_QUEUE_EMPTY(&query_result)) {
H5X_db_entry_t *entry;
H5X_DB_LOG_DEBUG("Query returns %zu references", query_result.n_elem);
H5Q_QUEUE_FOREACH(entry, &query_result, entry)
print_ref(entry->ref);
}
+#endif
H5X_DB_LOG_DEBUG("###########################");
/* Fill result */
@@ -1289,6 +1658,10 @@ H5X__db_query_components(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
if (FAIL == H5X__db_query_singleton(db, query_id, result))
HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to compare query");
} else {
+#ifdef H5X_DB_USE_JOIN
+ if (FAIL == H5X__db_query_combine(db, 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_db_head_t result1 = H5Q_QUEUE_HEAD_INITIALIZER(result1);
@@ -1343,6 +1716,7 @@ H5X__db_query_components(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
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");
+#endif
}
done:
@@ -1354,8 +1728,9 @@ H5X__db_query_singleton(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
{
DB *dbp;
DBC *dbcp = NULL; /* Handle of database cursor used for getting the data. */
- DBT key; /* The key from dbcp->get() */
- DBT data; /* The data from dbcp->get() */
+ DBT skey; /* The secondary key from dbcp->get() */
+ DBT pkey; /* The primary key from dbcp->get() */
+ DBT pdata; /* The data from dbcp->get() */
int db_ret;
H5Q_t *query; /* TODO */
H5Q_type_t query_type;
@@ -1364,8 +1739,9 @@ H5X__db_query_singleton(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
FUNC_ENTER_NOAPI_NOINIT
/* Initialize key/data */
- HDmemset(&key, 0, sizeof(DBT));
- HDmemset(&data, 0, sizeof(DBT));
+ HDmemset(&skey, 0, sizeof(DBT));
+ HDmemset(&pkey, 0, sizeof(DBT));
+ HDmemset(&pdata, 0, sizeof(DBT));
if (FAIL == H5Qget_type(query_id, &query_type))
HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
@@ -1377,27 +1753,24 @@ H5X__db_query_singleton(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
switch (query_type) {
case H5Q_TYPE_LINK_NAME:
{
- /* DB_NEXT moves the cursor to the next record. */
- key.data = query->query.select.elem.link_name.name;
- key.size = (u_int32_t)(HDstrlen(query->query.select.elem.link_name.name) + 1);
+ skey.data = query->query.select.elem.link_name.name;
+ skey.size = (u_int32_t)(HDstrlen(query->query.select.elem.link_name.name) + 1);
dbp = db->link_names_db;
}
break;
case H5Q_TYPE_ATTR_NAME:
{
- /* DB_NEXT moves the cursor to the next record. */
- key.data = query->query.select.elem.attr_name.name;
- key.size = (u_int32_t)(HDstrlen(query->query.select.elem.attr_name.name) + 1);
+ skey.data = query->query.select.elem.attr_name.name;
+ skey.size = (u_int32_t)(HDstrlen(query->query.select.elem.attr_name.name) + 1);
dbp = db->attr_names_db;
}
break;
case H5Q_TYPE_ATTR_VALUE:
{
- /* DB_NEXT moves the cursor to the next record. */
- key.data = query->query.select.elem.data_elem.value;
- key.size = (u_int32_t)query->query.select.elem.data_elem.type_size;
+ skey.data = query->query.select.elem.data_elem.value;
+ skey.size = (u_int32_t)query->query.select.elem.data_elem.type_size;
dbp = db->attr_values_db;
}
@@ -1413,24 +1786,18 @@ H5X__db_query_singleton(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
if ((db_ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0)
dbp->err(dbp, db_ret, "DB->cursor");
- db_ret = dbcp->get(dbcp, &key, &data, DB_SET);
+ db_ret = dbcp->pget(dbcp, &skey, &pkey, &pdata, DB_SET);
while (db_ret != DB_NOTFOUND) {
H5X_db_entry_t *entry;
-// if (query_type == H5Q_TYPE_ATTR_VALUE)
-// H5X_DB_LOG_DEBUG("key: %d, key size: %u", *((int *)key.data), (unsigned int)key.size);
-// else
-// H5X_DB_LOG_DEBUG("key: %s, key size: %u", (char *)key.data, (unsigned int)key.size);
-
if (NULL == (entry = (H5X_db_entry_t *) H5MM_malloc(sizeof(H5X_db_entry_t))))
HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry");
entry->ref = NULL;
- entry->type = query_type;
- if (NULL == (entry->ref = H5R_decode(data.data)))
+ if (NULL == (entry->ref = H5R_decode(pkey.data)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't decode reference");
H5Q_QUEUE_INSERT_TAIL(result, entry, entry);
- db_ret = dbcp->get(dbcp, &key, &data, DB_NEXT_DUP);
+ db_ret = dbcp->pget(dbcp, &skey, &pkey, &pdata, DB_NEXT_DUP);
}
done:
@@ -1440,6 +1807,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_query_singleton */
+#ifndef H5X_DB_USE_JOIN
static herr_t
H5X__db_query_combine(H5Q_combine_op_t combine_op, H5X_db_head_t *result1,
H5X_db_head_t *result2, H5X_db_head_t *result)
@@ -1504,4 +1872,202 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5X__db_query_combine */
+#else
+
+static herr_t
+H5X__db_query_parse(hid_t query_id, H5X_db_query_head_t *query_list)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5Q_combine_op_t combine_op;
+ hid_t query1_id, query2_id;
+ H5Q_type_t query1_type, query2_type;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (FAIL == H5Qget_combine_op(query_id, &combine_op))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get combine op");
+ if (combine_op != H5Q_COMBINE_AND)
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported combine op");
+ if (FAIL == H5Qget_components(query_id, &query1_id, &query2_id))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get components");
+ if (FAIL == H5Qget_type(query1_id, &query1_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+ if (FAIL == H5Qget_type(query2_id, &query2_type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+
+ if (query1_type != H5Q_TYPE_MISC) {
+ H5X_db_query_entry_t *entry;
+
+ /* Add query to query list */
+ if (NULL == (entry = (H5X_db_query_entry_t *) H5MM_malloc(sizeof(H5X_db_query_entry_t))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate query entry");
+ entry->query_id = query1_id;
+ H5Iinc_ref(query1_id);
+ entry->type = query1_type;
+
+ H5Q_QUEUE_INSERT_TAIL(query_list, entry, entry);
+ } else {
+ if (FAIL == H5X__db_query_parse(query1_id, query_list))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+ }
+
+ if (query2_type != H5Q_TYPE_MISC) {
+ H5X_db_query_entry_t *entry;
+
+ /* Add query to query list */
+ if (NULL == (entry = (H5X_db_query_entry_t *) H5MM_malloc(sizeof(H5X_db_query_entry_t))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate query entry");
+ entry->query_id = query2_id;
+ H5Iinc_ref(query2_id);
+ entry->type = query2_type;
+
+ H5Q_QUEUE_INSERT_TAIL(query_list, entry, entry);
+ } else {
+ if (FAIL == H5X__db_query_parse(query2_id, query_list))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTGET, FAIL, "unable to get query type");
+ }
+
+done:
+ H5Qclose(query1_id);
+ H5Qclose(query2_id);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__db_query_parse */
+
+static herr_t
+H5X__db_query_combine(H5X_db_t *db, hid_t query_id, H5X_db_head_t *result)
+{
+ DBC **carray = NULL;
+ H5X_db_query_head_t query_list = H5Q_QUEUE_HEAD_INITIALIZER(query_list);
+ H5X_db_query_entry_t *query_entry;
+ herr_t ret_value = SUCCEED; /* Return value */
+ int db_ret;
+ DBT join_key, join_data;
+ DBC *join_curs = NULL;
+ hbool_t obj_ref = FALSE;
+ int i = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Step 1: Get all leaves */
+ if (FAIL == H5X__db_query_parse(query_id, &query_list))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to parse query");
+
+ /* Initialize key/data */
+ HDmemset(&join_key, 0, sizeof(DBT));
+ HDmemset(&join_data, 0, sizeof(DBT));
+
+ /* Initialize carray (must keep NULL at the end) */
+ if (NULL == (carray = (DBC **) H5MM_malloc(sizeof(DBC *) * (query_list.n_elem + 1))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate carray");
+ carray[query_list.n_elem] = NULL;
+
+ /* Step 2: For each leaf / associate right table */
+ H5Q_QUEUE_FOREACH(query_entry, &query_list, entry) {
+ H5Q_t *query;
+ DB *sdbp;
+ DBT key, data;
+
+ /* Initialize key/data */
+ HDmemset(&key, 0, sizeof(DBT));
+ HDmemset(&data, 0, sizeof(DBT));
+
+ /* TODO add public function */
+ if (NULL == (query = (H5Q_t *) H5I_object_verify(query_entry->query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID");
+
+ switch (query_entry->type) {
+ case H5Q_TYPE_LINK_NAME:
+ {
+ key.data = query->query.select.elem.link_name.name;
+ key.size = (u_int32_t)(HDstrlen(query->query.select.elem.link_name.name) + 1);
+
+ sdbp = db->attr_link_names_db;
+ /* If the query is AND with link name, return object reference */
+ obj_ref = TRUE;
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ key.data = query->query.select.elem.attr_name.name;
+ key.size = (u_int32_t)(HDstrlen(query->query.select.elem.attr_name.name) + 1);
+
+ sdbp = db->attr_names_db;
+ }
+ break;
+ case H5Q_TYPE_ATTR_VALUE:
+ {
+ key.data = query->query.select.elem.data_elem.value;
+ key.size = (u_int32_t)query->query.select.elem.data_elem.type_size;
+
+ sdbp = db->attr_values_db;
+ }
+ break;
+ case H5Q_TYPE_DATA_ELEM:
+ case H5Q_TYPE_MISC:
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type");
+ break;
+ }
+ /* Acquire a cursor for sequential access to the database. */
+ if ((db_ret = sdbp->cursor(sdbp, NULL, &carray[i], 0)) != 0)
+ sdbp->err(sdbp, db_ret, "DB->cursor");
+ if ((db_ret = carray[i]->get(carray[i], &key, &data, DB_SET)) != 0)
+ sdbp->err(sdbp, db_ret, "DB->cursor");
+
+ i++;
+ }
+
+ /* Step 3: Create join cursor */
+ if ((db_ret = db->attr_refs_db->join(db->attr_refs_db, carray, &join_curs, 0)) != 0)
+ db->attr_refs_db->err(db->attr_refs_db, db_ret, "DB->join");
+
+ /* Iterate using the join cursor */
+ while ((db_ret = join_curs->get(join_curs, &join_key, &join_data, 0)) == 0) {
+ /* Do interesting things with the key and data */
+ H5X_db_entry_t *entry;
+
+ if (NULL == (entry = (H5X_db_entry_t *) H5MM_malloc(sizeof(H5X_db_entry_t))))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry");
+ entry->ref = NULL;
+ if (NULL == (entry->ref = H5R_decode(join_key.data)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't decode reference");
+ /* If the result is an object reference, simply cast the reference */
+ if (obj_ref && FAIL == H5R_cast(entry->ref, H5R_EXT_OBJECT))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCONVERT, FAIL, "can't convert reference");
+
+ H5Q_QUEUE_INSERT_TAIL(result, entry, entry);
+ }
+
+ /*
+ * If we exited the loop because we ran out of records,
+ * then it has completed successfully.
+ */
+ if (db_ret == DB_NOTFOUND) {
+ /*
+ * Close all our cursors and databases as is appropriate,
+ * then exit with a normal exit status (0).
+ */
+ }
+
+done:
+ /* Close the cursor */
+ if (join_curs)
+ join_curs->close(join_curs);
+ if (carray) {
+ int j;
+ for (j = 0; j < i; j++) {
+ carray[j]->close(carray[j]);
+ }
+ H5MM_free(carray);
+ }
+ while (!H5Q_QUEUE_EMPTY(&query_list)) {
+ H5X_db_query_entry_t *entry = H5Q_QUEUE_FIRST(&query_list);
+ H5Q_QUEUE_REMOVE_HEAD(&query_list, entry);
+ H5Qclose(entry->query_id);
+ H5MM_free(entry);
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5X__db_query_combine1 */
+#endif
+
#endif /* H5_HAVE_DB */