lib: field path: have a specific item for "current array element"
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 24 Apr 2019 04:19:06 +0000 (00:19 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 3 May 2019 22:19:39 +0000 (18:19 -0400)
commit1d4afa5f4367825e5d7b0bd9846354319f64027f
treef2e8f43fb4990541aeb8a9cfd15da87950ee7730
parentc16748c703b0786c5daf4eda3a8af1da8bdf9cd8
lib: field path: have a specific item for "current array element"

This patch makes a field path object have a list of items, which are
unique objects, instead of simple member/choice indexes. One type of
item is an index item (which contains only a structure member or variant
choice index) while the other is a "current array element" item.

The previous algorithm to "walk" a field path from a known root field
or field class was (Python pseudocode):

    current_fc = root_fc
    i = 0

    while i < len(field_path):
        index = field_path[i]

        if type(current_fc) is in (StructureFieldClass, VariantFieldClass):
            current_fc = current_fc[index]
            i += 1
        else:
            current_fc = current_fc.element_field_class

As you can see, there's no special field path index to indicate that
we're in the current element of an array: you just pass through arrays
without "consuming" a field path index.

In TSDL, it can happen like this:

    fields := struct {
        struct {
            int abc;
            int len;
            string strings[len];
        } s[4];
    };

Currently, the field path of the `strings` dynamic array is:

    event payload: [0, 1]

With this patch, the same field path becomes:

    event payload: [0, <CUR>, 1]

and the walking algorithm above becomes:

    current_fc = root_fc

    for item in field_path:
        if type(current_fc) is in (StructureFieldClass, VariantFieldClass):
            assert(type(item) is IndexFieldPathItem)
            current_fc = current_fc[item.index]
        else:
            assert(type(item) is CurrentArrayElementFieldPathItem)
            current_fc = current_fc.element_field_class

or it could also be:

    current_fc = root_fc

    for item in field_path:
        if type(item) is IndexFieldPathItem:
            current_fc = current_fc[item.index]
        else:
            assert(type(item) is CurrentArrayElementFieldPathItem)
            current_fc = current_fc.element_field_class

There is no special case with this now more complete field path.

I also intend to have something like this in CTF 2. Currently, CTF 1.8
does not allow a relative field path to be rewritten as an absolute
field path if it's in an array. For example, you could not rewrite the
TSDL example above as:

    fields := struct {
        struct {
            int abc;
            int len;
            string strings[event.fields.s.len];
        } s[4];
    };

Babeltrace 1 does not accept this, so Babeltrace 2 does not either, and
I don't think CTF is designed this way. I think it's limiting, so I'm
making this patch to accommodate CTF 2 in the future.

This patch also opens the door to having other types of field path items
in the future, like any element within an array (as long as it's before
the requesting dynamic array or variant field), so that you could have:

    event payload: [1, 3, 0]
                    ^  ^  ^-- first member of a structure
                    |  `----- fourth element of an array
                    `-------- second member of a structure

This patch also makes the `flt.lttng-utils.debug-info` and `sink.ctf.fs`
component classes use the modified API.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
include/babeltrace/common-internal.h
include/babeltrace/trace-ir/field-path-const.h
include/babeltrace/trace-ir/field-path-internal.h
include/babeltrace/types.h
lib/lib-logging.c
lib/trace-ir/field-path.c
lib/trace-ir/resolve-field-path.c
plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c
plugins/lttng-utils/debug-info/trace-ir-metadata-field-class-copy.c
This page took 0.026154 seconds and 4 git commands to generate.