H5Literate2 problem - names ok, IDs not


#1

I’m simply trying to read the objects in a group using H5Literate2 and an iterator callback. Below is a snippet of the iterator function. When I run the search on a group that I know has 4 groups in it, the name variable is correct, but loc_id is the same for all of them.

Here’s a screenshot of some debug output: I’m printing the ID, name (an IP Address in this case) and the type.
image

herr_t read_subgroups_iter(hid_t loc_id, const char* name, const H5L_info_t* info, void* operator_data)
{
    herr_t          status;
    H5O_info_t      infobuf;
    unsigned int    fields = 1;

    status = H5Oget_info3(loc_id, &infobuf, fields);
...

Please can someone point me in the right direction? Although it’s been fun coding this up, with structures to aggregate the results, am I missing a trick and there’s a simpler helper function to do this? I looked in the Lite API but didn’t find.

EDIT I’ve confirmed that the value of loc_id I’m getting is different to the id of the group I’m doing the search on


#2

the HDF5 tools library does something similar. Start with the “h5trav_visit” function in tools/lib/h5trav.c

int
h5trav_visit(hid_t fid, const char *grp_name, hbool_t visit_start, hbool_t recurse,
             h5trav_obj_func_t visit_obj, h5trav_lnk_func_t visit_lnk, void *udata, unsigned fields)
{
    trav_visitor_t visitor; /* Visitor structure for objects */
    int            ret_value = 0;

    /* Init visitor structure */
    visitor.visit_obj = visit_obj;
    visitor.visit_lnk = visit_lnk;
    visitor.udata     = udata;

    /* Traverse all objects in the file, visiting each object & link */
    if (traverse(fid, grp_name, visit_start, recurse, &visitor, fields) < 0)
        H5TOOLS_GOTO_ERROR((-1), "traverse failed");

done:
    return ret_value;

This calls the traverse function which I think is what you are trying to accomplish.


#3

Thanks I will take a look. Any idea why I’m getting that odd result on IDs? I’m assuming it’s not a bug in H5 but something in my code.


#4

The output is expected. The, possibly empty, link destination in the callback is name relative to loc_id.
I think you’ve compounded two issues:

  1. Since you are using H5Literate, the first thing to do in the callback is to call H5Lget_info. That will tell you what kind of link your are dealing with (hard, soft, external, user-defined), which dictates how aggressive you can be regarding link traversal. Anything but hard links (H5L_TYPE_HARD) needs to be handled with caution because the destination might be nirvana.
  2. Once you are confident that the link is traversable (to an object), you can use H5Oget_info_by_name (not H5Oget_info!) to learn more about the object.

OK? G.


#5

Thanks. I feel I’m not understanding the use of IDs, so if I can just work with the returned names and types (which is working fine) then I’m good. So if do this:

  • use my code to find the names and types of objects in a group (say they are more groups as in my screenshot above)
  • open a group using H5Gopen2 which takes the group name and returns the ID, which I can use in other functions…

It’s as simple as that? These IDs that appear in the iterator aren’t needed? By me anyway.


#6

IDs are just ephemeral API handles. They exist only for the duration of an [create,open] - close cycle.
The situation can be illustrated as follows:

    "g1"      "l1"
 o ------> o ------> o
id1       id2       id3

WHERE
o          - object
id         - API handle
->         - link
"g1", "l1" - link names

We can work with the object identified by handle id3 directly through the API. If a name were required, we’d pass “.” (dot). We can refer to the same object as (loc_id=id2, name="l1") or(loc_id=id1, name="g1/l1"). OK?

If you have an ID, close it eventually (or resource leaks will ensue). You can check if an identifier is valid (wasn’t closed) via H5Iis_valid.

Yes.

By ‘iterator’ you mean the callback function, right? Whether you need the loc_id, etc. in such a callback depends on what the callback is supposed to achieve. If you just want to print the name, no you don’t. But remember that name has meaning only relative to loc_id.

G.


#7

Thanks. I do get how the IDs work for the open/close cycle and the use of paths in general H5Gopen(), H5GClose() calls. That is all working fine for me.

I was confused about what loc_id meant in the callback (iterator) function. Now I can see that it means the (ephemeral) ID of the containing group. And so a call to H5Oget_info_by_name(loc_id, name) as you suggested gets me the info I want on each object in that group. Yes it works.

The reason I was confused is that I found some sample code that then made a call to H5G_get_info(loc_id,…) i.e. no name argument. Implying that loc_id is the ID of each object. I see now why that doesn’t work.

(If my interpretation is wrong, please correct!)