diff options
author | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2016-06-13 20:24:23 (GMT) |
---|---|---|
committer | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2016-11-29 23:42:33 (GMT) |
commit | f3da9b2a1952cba4484647aaaeb153994f474602 (patch) | |
tree | 1d6d2980623860da59b8fdf8e787115b80c98a17 /src | |
parent | a4b81fe620b8ecf7e022544b00332e825ca33db0 (diff) | |
download | hdf5-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.c | 1128 |
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 */ |