diff options
author | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2015-12-03 18:37:50 (GMT) |
---|---|---|
committer | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2016-11-29 23:42:31 (GMT) |
commit | f38e0c1fca9f7db1f2ac49352d92ee01210313e8 (patch) | |
tree | e974d70ddcc97dcdee746a8c15e195c8d9e09555 | |
parent | f545fa003ec9319a2ac1a9b299c605adb7a86ad9 (diff) | |
download | hdf5-f38e0c1fca9f7db1f2ac49352d92ee01210313e8.zip hdf5-f38e0c1fca9f7db1f2ac49352d92ee01210313e8.tar.gz hdf5-f38e0c1fca9f7db1f2ac49352d92ee01210313e8.tar.bz2 |
Add H5Qapply_multi for cross container queries
Fix H5Q code to use external references
Update query test after changes
-rw-r--r-- | src/H5Q.c | 264 | ||||
-rw-r--r-- | src/H5Qprivate.h | 1 | ||||
-rw-r--r-- | src/H5Qpublic.h | 2 | ||||
-rw-r--r-- | test/query.c | 143 |
4 files changed, 341 insertions, 69 deletions
@@ -197,12 +197,7 @@ typedef enum H5Q_match_type_t { /* The different kinds of native types we can ma typedef struct H5Q_ref_entry_t H5Q_ref_entry_t; struct H5Q_ref_entry_t { - H5R_type_t ref_type; - union { - hreg_ref_t reg; - hobj_ref_t obj; - hattr_ref_t attr; - } ref; + href_t *ref; H5Q_QUEUE_ENTRY(H5Q_ref_entry_t) entry; }; @@ -2117,7 +2112,7 @@ static herr_t H5Q__apply_object_link(H5G_loc_t *loc, const char *name, const H5O_info_t *oinfo, void *udata) { - hobj_ref_t ref_buf; + href_t *ref; hbool_t result; H5Q_apply_arg_t *args = (H5Q_apply_arg_t *) udata; const char *link_name = NULL; @@ -2147,9 +2142,9 @@ H5Q__apply_object_link(H5G_loc_t *loc, const char *name, const H5O_info_t *oinfo H5Q_LOG_DEBUG("Match link name: %s (%s)\n", link_name, name); /* Keep object reference */ - if (FAIL == H5R_create(&ref_buf, H5R_OBJECT, loc, name, H5AC_dxpl_id)) + if (NULL == (ref = H5R_create_ext_object(loc, name, H5AC_dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create object reference"); - if (FAIL == H5Q__view_append(args->view, H5R_OBJECT, &ref_buf)) + if (FAIL == H5Q__view_append(args->view, H5R_EXT_OBJECT, ref)) HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append object reference to view"); done: @@ -2169,7 +2164,7 @@ static herr_t H5Q__apply_object_data(H5G_loc_t *loc, const char *name, const H5O_info_t *oinfo, void *udata) { - hreg_ref_t ref_buf = H5R_REG_REF_INITIALIZER; + href_t *ref; H5Q_apply_arg_t *args = (H5Q_apply_arg_t *) udata; hid_t obj_id = FAIL; H5S_t *dataspace = NULL; @@ -2208,16 +2203,9 @@ H5Q__apply_object_data(H5G_loc_t *loc, const char *name, const H5O_info_t *oinfo *(args->result) = H5Q_REF_REG; /* Keep dataset region reference */ - if (FAIL == H5R_create(&ref_buf, H5R_REGION, loc, name, H5AC_dxpl_id, dataspace)) + if (NULL == (ref = H5R_create_ext_region(loc, name, H5AC_dxpl_id, dataspace))) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for region reference"); - - H5Q_LOG_DEBUG("Region reference size: %zu\n", ref_buf.buf_size); - if (NULL == (ref_buf.buf = H5MM_malloc(ref_buf.buf_size))) - HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, FAIL, "can't allocate region reference buffer"); - - if (FAIL == H5R_create(&ref_buf, H5R_REGION, loc, name, H5AC_dxpl_id, dataspace)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create region reference"); - if (FAIL == H5Q__view_append(args->view, H5R_REGION, &ref_buf)) + if (FAIL == H5Q__view_append(args->view, H5R_EXT_REGION, ref)) HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append region reference to view"); done: @@ -2341,7 +2329,7 @@ H5Q__apply_object_attr_name(H5A_t *attr, void *udata) H5Q_apply_attr_arg_t *args = (H5Q_apply_attr_arg_t *) udata; char *name = NULL; size_t name_len; - hattr_ref_t ref_buf = H5R_ATTR_REF_INITIALIZER; + href_t *ref; hbool_t result = FALSE; herr_t ret_value = SUCCEED; /* Return value */ @@ -2368,16 +2356,9 @@ H5Q__apply_object_attr_name(H5A_t *attr, void *udata) H5Q_LOG_DEBUG("Match attribute name: %s\n", (const char *) name); /* Keep attribute reference */ - if (FAIL == H5R_create(&ref_buf, H5R_ATTR, args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name)) + if (NULL == (ref = H5R_create_ext_attr(args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name))) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference"); - - H5Q_LOG_DEBUG("Attribute reference size: %zu\n", ref_buf.buf_size); - if (NULL == (ref_buf.buf = H5MM_malloc(ref_buf.buf_size))) - HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, FAIL, "can't allocate attribute reference buffer"); - - if (FAIL == H5R_create(&ref_buf, H5R_ATTR, args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create attribute reference"); - if (FAIL == H5Q__view_append(args->apply_args->view, H5R_ATTR, &ref_buf)) + if (FAIL == H5Q__view_append(args->apply_args->view, H5R_EXT_ATTR, ref)) HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view"); done: @@ -2409,7 +2390,7 @@ H5Q__apply_object_attr_value(H5A_t *iter_attr, void *udata) size_t nelmts, elmt_size; H5S_sel_iter_op_t iter_op; /* Operator for iteration */ H5Q_apply_attr_elem_arg_t iter_args; - hattr_ref_t ref_buf = H5R_ATTR_REF_INITIALIZER; + href_t *ref; hbool_t result = FALSE; herr_t ret_value = SUCCEED; /* Return value */ @@ -2470,16 +2451,9 @@ H5Q__apply_object_attr_value(H5A_t *iter_attr, void *udata) H5Q_LOG_DEBUG("Match value of attribute name: %s\n", (const char *) name); /* Keep attribute reference */ - if (FAIL == H5R_create(&ref_buf, H5R_ATTR, args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name)) + if (NULL == (ref = H5R_create_ext_attr(args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name))) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get buffer size for attribute reference"); - - H5Q_LOG_DEBUG("Attribute reference size: %zu\n", ref_buf.buf_size); - if (NULL == (ref_buf.buf = H5MM_malloc(ref_buf.buf_size))) - HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, FAIL, "can't allocate attribute reference buffer"); - - if (FAIL == H5R_create(&ref_buf, H5R_ATTR, args->loc, args->loc_name, H5AC_dxpl_id, (const char *) name)) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create attribute reference"); - if (FAIL == H5Q__view_append(args->apply_args->view, H5R_ATTR, &ref_buf)) + if (FAIL == H5Q__view_append(args->apply_args->view, H5R_EXT_ATTR, ref)) HGOTO_ERROR(H5E_QUERY, H5E_CANTAPPEND, FAIL, "can't append attribute reference to view"); done: @@ -2545,24 +2519,20 @@ H5Q__view_append(H5Q_view_t *view, H5R_type_t ref_type, void *ref) HDassert(view); HDassert(ref); - if (NULL == (ref_entry = (H5Q_ref_entry_t *) H5MM_calloc(sizeof(H5Q_ref_entry_t)))) + if (NULL == (ref_entry = (H5Q_ref_entry_t *) H5MM_malloc(sizeof(H5Q_ref_entry_t)))) HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate ref entry"); - ref_entry->ref_type = ref_type; + ref_entry->ref = ref; switch (ref_type) { - case H5R_REGION: - HDmemcpy(&ref_entry->ref.reg, ref, sizeof(hreg_ref_t)); + case H5R_EXT_REGION: H5Q_QUEUE_INSERT_TAIL(&view->reg_refs, ref_entry, entry); break; - case H5R_OBJECT: - HDmemcpy(&ref_entry->ref.obj, ref, sizeof(hobj_ref_t)); + case H5R_EXT_OBJECT: H5Q_QUEUE_INSERT_TAIL(&view->obj_refs, ref_entry, entry); break; - case H5R_ATTR: - HDmemcpy(&ref_entry->ref.attr, ref, sizeof(hattr_ref_t)); + case H5R_EXT_ATTR: H5Q_QUEUE_INSERT_TAIL(&view->attr_refs, ref_entry, entry); break; - case H5R_DATASET_REGION: case H5R_BADTYPE: case H5R_MAXTYPE: default: @@ -2672,8 +2642,8 @@ H5Q__view_write(H5G_t *grp, H5Q_view_t *view) &view->attr_refs }; const char *dset_name[H5Q_VIEW_REF_NTYPES] = { H5Q_VIEW_REF_REG_NAME, H5Q_VIEW_REF_OBJ_NAME, H5Q_VIEW_REF_ATTR_NAME }; - hid_t ref_types[H5Q_VIEW_REF_NTYPES] = { H5T_STD_REF_REG, - H5T_STD_REF_OBJ, H5T_STD_REF_ATTR }; + hid_t ref_types[H5Q_VIEW_REF_NTYPES] = { H5T_STD_REF_EXT_REG, + H5T_STD_REF_EXT_OBJ, H5T_STD_REF_EXT_ATTR }; herr_t ret_value = SUCCEED; /* Return value */ int i; @@ -2714,7 +2684,7 @@ H5Q__view_write(H5G_t *grp, H5Q_view_t *view) if (FAIL == H5S_select_hyperslab(space, H5S_SELECT_SET, &start, NULL, &count, NULL)) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") if (FAIL == H5D_write(dset, FALSE, ref_types[i], mem_space, space, - H5P_DATASET_XFER_DEFAULT, &ref_entry->ref)) + H5P_DATASET_XFER_DEFAULT, ref_entry->ref)) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write dataset"); if (FAIL == H5S_close(mem_space)) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataspace"); @@ -2763,13 +2733,197 @@ H5Q__view_free(H5Q_view_t *view) while (!H5Q_QUEUE_EMPTY(refs[i])) { H5Q_ref_entry_t *ref_entry = H5Q_QUEUE_FIRST(refs[i]); H5Q_QUEUE_REMOVE_HEAD(refs[i], entry); - if (ref_entry->ref_type == H5R_REGION) - H5MM_free(ref_entry->ref.reg.buf); - if (ref_entry->ref_type == H5R_ATTR) - H5MM_free(ref_entry->ref.attr.buf); + /* TODO call H5Rdestroy */ + H5R_destroy(ref_entry->ref); H5MM_free(ref_entry); } } FUNC_LEAVE_NOAPI(ret_value) } /* end H5Q__view_free */ + +/*------------------------------------------------------------------------- + * Function: H5Qapply_multi + * + * Purpose: Apply a query on multiple locations and return the result. + * Parameters, which the query applies to, are determined by the type of the + * query. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Qapply_multi(size_t loc_count, hid_t *loc_ids, hid_t query_id, + unsigned *result, hid_t vcpl_id) +{ + H5Q_t *query = NULL; + H5G_loc_t *locs = NULL; + H5G_t *ret_grp; + hid_t ret_value; + int i; + + FUNC_ENTER_API(FAIL) + + /* Check args and get the query objects */ + if (!loc_count) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "loc_count cannot be NULL"); + if (NULL == (locs = (H5G_loc_t *) H5MM_malloc(loc_count * sizeof(H5G_loc_t)))) + HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate locs buffer"); + for (i = 0; i < loc_count; i++) { + if (FAIL == H5G_loc(loc_ids[i], &locs[i])) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); + } + if (NULL == (query = (H5Q_t *) H5I_object_verify(query_id, H5I_QUERY))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID"); + if (!result) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for result"); + + /* Get the default view creation property list if the user didn't provide one */ + /* TODO fix that */ + if (H5P_DEFAULT == vcpl_id) + vcpl_id = H5P_INDEX_ACCESS_DEFAULT; + else + if (TRUE != H5P_isa_class(vcpl_id, H5P_INDEX_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not index access parms"); + + /* Apply query */ + if (NULL == (ret_grp = H5Q_apply_multi(loc_count, locs, loc_ids, query, result, vcpl_id))) + HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query"); + + if (FAIL == (ret_value = H5I_register(H5I_GROUP, ret_grp, TRUE))) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group"); + +done: + H5MM_free(locs); + FUNC_LEAVE_API(ret_value) +} /* end H5Qapply_multi() */ + +/*------------------------------------------------------------------------- + * Function: H5Q_apply_multi + * + * Purpose: Private function for H5Qapply_multi. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +H5G_t * +H5Q_apply_multi(size_t loc_count, const H5G_loc_t *locs, hid_t *loc_ids, + const H5Q_t *query, unsigned *result, hid_t H5_ATTR_UNUSED vcpl_id) +{ + H5Q_view_t view = H5Q_VIEW_INITIALIZER(view); /* Resulting view */ + H5Q_ref_head_t *refs[H5Q_VIEW_REF_NTYPES] = { &view.reg_refs, &view.obj_refs, &view.attr_refs }; + unsigned multi_result = 0; + H5G_t *ret_grp = NULL; /* New group created */ + H5G_t *ret_value = NULL; /* Return value */ + H5P_genclass_t *pclass = NULL; + unsigned flags; + hid_t fapl_id = FAIL; + H5F_t *new_file = NULL; + H5G_loc_t file_loc; + size_t i; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(loc_count); + HDassert(locs); + HDassert(loc_ids); + HDassert(query); + HDassert(result); + + /* TODO Serial iteration for now */ + for (i = 0; i < loc_count; i++) { + H5Q_view_t loc_view = H5Q_VIEW_INITIALIZER(loc_view); /* Resulting view */ + H5Q_ref_head_t *loc_refs[H5Q_VIEW_REF_NTYPES] = { &loc_view.reg_refs, &loc_view.obj_refs, &loc_view.attr_refs }; + unsigned loc_result; + H5Q_apply_arg_t args; + int j; + + /* Create new view and init args */ + args.query = query; + args.result = &loc_result; + args.view = &loc_view; + + if (FAIL == H5O_visit(loc_ids[i], ".", H5_INDEX_NAME, H5_ITER_NATIVE, H5Q__apply_iterate, + &args, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, NULL, "object visitation failed"); + + multi_result |= loc_result; + /* Simply concatenate results from sub-view */ + for (j = 0; j < H5Q_VIEW_REF_NTYPES; j++) { + H5Q_QUEUE_CONCAT(refs[j], loc_refs[j]); + } + } + + if (!H5Q_QUEUE_EMPTY(&view.reg_refs)) + H5Q_LOG_DEBUG("Number of reg refs: %zu\n", view.reg_refs.n_elem); + if (!H5Q_QUEUE_EMPTY(&view.obj_refs)) + H5Q_LOG_DEBUG("Number of obj refs: %zu\n", view.obj_refs.n_elem); + if (!H5Q_QUEUE_EMPTY(&view.attr_refs)) + H5Q_LOG_DEBUG("Number of attr refs: %zu\n", view.attr_refs.n_elem); + + /* Get property list class */ + if (NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(H5P_FILE_ACCESS, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list class"); + + /* Create the new property list */ + if (FAIL == (fapl_id = H5P_create_id(pclass, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "unable to create property list"); + + /* Use the core VFD to store the view */ + if (FAIL == H5Pset_fapl_core(fapl_id, H5Q_VIEW_CORE_INCREMENT, FALSE)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set property list to core VFD"); + + /* Create a new file or truncate an existing file. */ + flags = H5F_ACC_EXCL | H5F_ACC_RDWR | H5F_ACC_CREAT; + if (NULL == (new_file = H5F_open("view", flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file"); + + /* Construct a group location for root group of the file */ + if (FAIL == H5G_root_loc(new_file, &file_loc)) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unable to create location for file") + + /* Create the new group & get its ID */ + if (NULL == (ret_grp = H5G_create_anon(&file_loc, H5P_GROUP_CREATE_DEFAULT, H5P_GROUP_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group"); + + /* Write view */ + if (FAIL == H5Q__view_write(ret_grp, &view)) + HGOTO_ERROR(H5E_QUERY, H5E_WRITEERROR, NULL, "can't write view"); + + *result = multi_result; + ret_value = ret_grp; + +done: + /* Release the group's object header, if it was created */ + if (ret_grp) { + H5O_loc_t *grp_oloc; /* Object location for group */ + + /* Get the new group's object location */ + if (NULL == (grp_oloc = H5G_oloc(ret_grp))) + HDONE_ERROR(H5E_SYM, H5E_CANTGET, NULL, "unable to get object location of group"); + + /* Decrement refcount on group's object header in memory */ + if (FAIL == H5O_dec_rc_by_loc(grp_oloc, H5AC_dxpl_id)) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object"); + } /* end if */ + + /* Cleanup on failure */ + if (NULL == ret_value) + if (ret_grp && (FAIL == H5G_close(ret_grp))) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release group"); + + /* Close the property list */ + if ((fapl_id != FAIL) && (H5I_dec_app_ref(fapl_id) < 0)) + HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, NULL, "can't close"); + + /* Attempt to close the file/mount hierarchy */ + if (new_file && (FAIL == H5F_try_close(new_file))) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close file") + + /* Free the view */ + H5Q__view_free(&view); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Q_apply_multi() */ diff --git a/src/H5Qprivate.h b/src/H5Qprivate.h index f88ea69..2f68866 100644 --- a/src/H5Qprivate.h +++ b/src/H5Qprivate.h @@ -108,5 +108,6 @@ H5_DLL H5Q_t *H5Q_decode(const unsigned char **buf); /* Apply query */ H5_DLL herr_t H5Q_apply_atom(const H5Q_t *query, hbool_t *result, ...); H5_DLL H5G_t *H5Q_apply(const H5G_loc_t *loc, hid_t loc_id, const H5Q_t *query, unsigned *result, hid_t vcpl_id); +H5_DLL H5G_t *H5Q_apply_multi(size_t loc_count, const H5G_loc_t *locs, hid_t *loc_ids, const H5Q_t *query, unsigned *result, hid_t vcpl_id); #endif /* _H5Qprivate_H */ diff --git a/src/H5Qpublic.h b/src/H5Qpublic.h index 9e1bf8b..30edc3d 100644 --- a/src/H5Qpublic.h +++ b/src/H5Qpublic.h @@ -89,6 +89,8 @@ H5_DLL hid_t H5Qdecode(const void *buf); /* Apply query */ H5_DLL herr_t H5Qapply_atom(hid_t query_id, hbool_t *result, ...); H5_DLL hid_t H5Qapply(hid_t loc_id, hid_t query_id, unsigned *result, hid_t vcpl_id); +H5_DLL hid_t H5Qapply_multi(size_t loc_count, hid_t *loc_ids, hid_t query_id, + unsigned *result, hid_t vcpl_id); #ifdef __cplusplus } diff --git a/test/query.c b/test/query.c index ff160d1..345f562 100644 --- a/test/query.c +++ b/test/query.c @@ -22,12 +22,16 @@ const char *FILENAME[] = { "query", "query_fastbit", + "query1", + "query2", + "query3", NULL }; #define NTUPLES 1024*4 #define NCOMPONENTS 1 #define MAX_NAME 64 +#define MULTI_NFILES 3 /* Create query */ static hid_t @@ -429,12 +433,12 @@ error: /* Read region */ static herr_t -test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) +test_query_read_selection(hid_t file, hid_t fapl, hid_t view, H5R_type_t rtype) { hid_t refs = H5I_BADID, ref_type = H5I_BADID, ref_space = H5I_BADID; size_t n_refs, ref_size, ref_buf_size; void *ref_buf= NULL; - uint8_t *ref_ptr = NULL; + href_t *ref_ptr = NULL; const char *ref_path; hid_t obj = H5I_BADID, type = H5I_BADID, space = H5I_BADID, mem_space = H5I_BADID; size_t n_elem, elem_size, buf_size; @@ -443,9 +447,9 @@ test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) if (rtype == H5R_REGION) ref_path = H5Q_VIEW_REF_REG_NAME; - if (rtype == H5R_OBJECT) + else if (rtype == H5R_OBJECT) ref_path = H5Q_VIEW_REF_OBJ_NAME; - if (rtype == H5R_ATTR) + else if (rtype == H5R_ATTR) ref_path = H5Q_VIEW_REF_ATTR_NAME; /* Get region references from view */ @@ -455,6 +459,7 @@ test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) if (0 == (n_refs = (size_t) H5Sget_select_npoints(ref_space))) FAIL_STACK_ERROR; printf("Found %zu reference(s)\n", n_refs); if (0 == (ref_size = H5Tget_size(ref_type))) FAIL_STACK_ERROR; + printf("Reference type size: %d\n", ref_size); /* Allocate buffer to hold data */ ref_buf_size = n_refs * ref_size; @@ -463,16 +468,27 @@ test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) if ((H5Dread(refs, ref_type, H5S_ALL, ref_space, H5P_DEFAULT, ref_buf)) < 0) FAIL_STACK_ERROR; /* Get dataset / space / type ID for the referenced dataset region */ - ref_ptr = (uint8_t *) ref_buf; + ref_ptr = (href_t *) ref_buf; for (i = 0; i < n_refs; i++) { char obj_path[MAX_NAME]; + char filename[MAX_NAME]; + hid_t loc = H5I_BADID; - if ((obj = H5Rdereference(file, H5P_DEFAULT, rtype, ref_ptr)) < 0) FAIL_STACK_ERROR; + if (file == H5I_BADID) { + if (H5Rget_filename(ref_ptr, filename, MAX_NAME) < 0) FAIL_STACK_ERROR; + printf("Found reference from file: %s\n", filename); + if ((loc = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR; + } else { + loc = file; + } + if ((obj = H5Rdereference(loc, H5P_DEFAULT, ref_ptr)) < 0) FAIL_STACK_ERROR; if (H5Iget_name(obj, obj_path, MAX_NAME) < 0) FAIL_STACK_ERROR; printf("Found reference from object: %s\n", obj_path); if (rtype == H5R_REGION) { - if ((space = H5Rget_region(file, H5R_REGION, ref_ptr)) < 0) FAIL_STACK_ERROR; + int j; + + if ((space = H5Rget_region(loc, ref_ptr)) < 0) FAIL_STACK_ERROR; if ((type = H5Dget_type(obj)) < 0) FAIL_STACK_ERROR; if (0 == (n_elem = (size_t) H5Sget_select_npoints(space))) FAIL_STACK_ERROR; if (0 == (elem_size = H5Tget_size(type))) FAIL_STACK_ERROR; @@ -489,8 +505,8 @@ test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) if ((H5Dread(obj, type, mem_space, space, H5P_DEFAULT, buf)) < 0) FAIL_STACK_ERROR; printf("Elements found are:\n"); - for (i = 0; i < n_elem; i++) - printf("%f ", buf[i]); + for (j = 0; j < n_elem; j++) + printf("%f ", buf[j]); printf("\n"); if (H5Sclose(mem_space) < 0) FAIL_STACK_ERROR; @@ -502,14 +518,15 @@ test_query_read_selection(hid_t file, hid_t view, H5R_type_t rtype) if (rtype == H5R_ATTR) { char attr_name[MAX_NAME]; - if (H5Rget_name(obj, rtype, ref_ptr, attr_name, MAX_NAME) < 0) FAIL_STACK_ERROR; + if (H5Rget_name(obj, ref_ptr, attr_name, MAX_NAME) < 0) FAIL_STACK_ERROR; printf("Attribute name: %s\n", attr_name); if (H5Aclose(obj) < 0) FAIL_STACK_ERROR; } else { if (H5Dclose(obj) < 0) FAIL_STACK_ERROR; } - ref_ptr += ref_size; + if ((file == H5I_BADID) && (H5Fclose(loc) < 0)) FAIL_STACK_ERROR; + ref_ptr = (href_t *)((uint8_t *) ref_ptr + ref_size); } if ((rtype == H5R_ATTR) || (rtype == H5R_REGION)) @@ -550,6 +567,7 @@ test_query_apply_view(const char *filename, hid_t fapl, unsigned idx_plugin) printf(" ...\n---\n"); /* Create a simple file for testing queries */ + printf("Creating test file \"%s\"\n", filename); if ((test_query_create_simple_file(filename, fapl, idx_plugin)) < 0) FAIL_STACK_ERROR; /* Open the file in read-only */ @@ -572,7 +590,7 @@ test_query_apply_view(const char *filename, hid_t fapl, unsigned idx_plugin) + ((float) (t2.tv_usec - t1.tv_usec)) / 1000.0f); if (!(result & H5Q_REF_REG)) FAIL_STACK_ERROR; - if (test_query_read_selection(file, view, H5R_REGION) < 0) FAIL_STACK_ERROR; + if (test_query_read_selection(file, fapl, view, H5R_REGION) < 0) FAIL_STACK_ERROR; if (H5Gclose(view) < 0) FAIL_STACK_ERROR; if (test_query_close(query)) FAIL_STACK_ERROR; @@ -585,7 +603,7 @@ test_query_apply_view(const char *filename, hid_t fapl, unsigned idx_plugin) if ((view = H5Qapply(file, query, &result, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; if (!(result & H5Q_REF_OBJ)) FAIL_STACK_ERROR; - if (test_query_read_selection(file, view, H5R_OBJECT) < 0) FAIL_STACK_ERROR; + if (test_query_read_selection(file, fapl, view, H5R_OBJECT) < 0) FAIL_STACK_ERROR; if (H5Gclose(view) < 0) FAIL_STACK_ERROR; if (test_query_close(query)) FAIL_STACK_ERROR; @@ -598,7 +616,7 @@ test_query_apply_view(const char *filename, hid_t fapl, unsigned idx_plugin) if ((view = H5Qapply(file, query, &result, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; if (!(result & H5Q_REF_ATTR)) FAIL_STACK_ERROR; - if (test_query_read_selection(file, view, H5R_ATTR) < 0) FAIL_STACK_ERROR; + if (test_query_read_selection(file, fapl, view, H5R_ATTR) < 0) FAIL_STACK_ERROR; if (H5Gclose(view) < 0) FAIL_STACK_ERROR; if (test_query_close(query)) FAIL_STACK_ERROR; @@ -619,6 +637,92 @@ error: return -1; } +static herr_t +test_query_apply_view_multi(const char filename[MULTI_NFILES][MAX_NAME], hid_t fapl, unsigned idx_plugin) +{ + hid_t files[MULTI_NFILES] = {H5I_BADID, H5I_BADID, H5I_BADID}; + hid_t view = H5I_BADID; + hid_t query = H5I_BADID; + struct timeval t1, t2; + unsigned result = 0; + int i; + + printf(" ...\n---\n"); + + /* Create simple files for testing queries */ + for (i = 0; i < MULTI_NFILES; i++) { + printf("Creating test file \"%s\"\n", filename[i]); + if ((test_query_create_simple_file(filename[i], fapl, idx_plugin)) < 0) FAIL_STACK_ERROR; + /* Open the file in read-only */ + if ((files[i] = H5Fopen(filename[i], H5F_ACC_RDONLY, fapl)) < 0) FAIL_STACK_ERROR; + } + + printf("\nRegion query\n"); + printf( "------------\n"); + + /* Test region query */ + if ((query = test_query_create_type(H5R_REGION)) < 0) FAIL_STACK_ERROR; + + HDgettimeofday(&t1, NULL); + + if ((view = H5Qapply_multi(MULTI_NFILES, files, query, &result, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; + + HDgettimeofday(&t2, NULL); + + printf("View creation time on region: %lf ms\n", + ((float) (t2.tv_sec - t1.tv_sec)) * 1000.0f + + ((float) (t2.tv_usec - t1.tv_usec)) / 1000.0f); + + if (!(result & H5Q_REF_REG)) FAIL_STACK_ERROR; + if (test_query_read_selection(H5I_BADID, fapl, view, H5R_REGION) < 0) FAIL_STACK_ERROR; + + if (H5Gclose(view) < 0) FAIL_STACK_ERROR; + if (test_query_close(query)) FAIL_STACK_ERROR; + + printf("\nObject query\n"); + printf( "------------\n"); + + /* Test object query */ + if ((query = test_query_create_type(H5R_OBJECT)) < 0) FAIL_STACK_ERROR; + if ((view = H5Qapply_multi(MULTI_NFILES, files, query, &result, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; + + if (!(result & H5Q_REF_OBJ)) FAIL_STACK_ERROR; + if (test_query_read_selection(H5I_BADID, fapl, view, H5R_OBJECT) < 0) FAIL_STACK_ERROR; + + if (H5Gclose(view) < 0) FAIL_STACK_ERROR; + if (test_query_close(query)) FAIL_STACK_ERROR; + + printf("\nAttribute query\n"); + printf( "---------------\n"); + + /* Test attribute query */ + if ((query = test_query_create_type(H5R_ATTR)) < 0) FAIL_STACK_ERROR; + if ((view = H5Qapply_multi(MULTI_NFILES, files, query, &result, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR; + + if (!(result & H5Q_REF_ATTR)) FAIL_STACK_ERROR; + if (test_query_read_selection(H5I_BADID, fapl, view, H5R_ATTR) < 0) FAIL_STACK_ERROR; + + if (H5Gclose(view) < 0) FAIL_STACK_ERROR; + if (test_query_close(query)) FAIL_STACK_ERROR; + + for (i = 0; i < MULTI_NFILES; i++) + if (H5Fclose(files[i]) < 0) FAIL_STACK_ERROR; + if (test_query_close(query)) FAIL_STACK_ERROR; + + printf("---\n..."); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(view); + for (i = 0; i < MULTI_NFILES; i++) + H5Fclose(files[i]); + test_query_close(query); + } H5E_END_TRY; + return -1; +} + int main(void) { @@ -626,6 +730,7 @@ main(void) #ifdef H5_HAVE_FASTBIT char filename_fastbit[MAX_NAME]; #endif + char filename_multi[MULTI_NFILES][MAX_NAME]; hid_t query = H5I_BADID, fapl = H5I_BADID; /* Reset library */ @@ -636,6 +741,10 @@ main(void) #ifdef H5_HAVE_FASTBIT h5_fixname(FILENAME[1], fapl, filename_fastbit, sizeof(filename_fastbit)); #endif + h5_fixname(FILENAME[2], fapl, filename_multi[0], sizeof(filename_multi[0])); + h5_fixname(FILENAME[3], fapl, filename_multi[1], sizeof(filename_multi[1])); + h5_fixname(FILENAME[4], fapl, filename_multi[2], sizeof(filename_multi[2])); + /* Check that no object is left open */ H5Pset_fclose_degree(fapl, H5F_CLOSE_SEMI); @@ -677,6 +786,12 @@ main(void) PASSED(); #endif + TESTING("query apply view multiple (no index)"); + + if (test_query_apply_view_multi(filename_multi, fapl, H5X_PLUGIN_NONE) < 0) FAIL_STACK_ERROR; + + PASSED(); + /* Verify symbol table messages are cached */ if(h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR |