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)
committerFrancis Deslauriers <francis.deslauriers@efficios.com>
Thu, 2 May 2019 20:50:15 +0000 (20:50 +0000)
commit66ddcddf20c698aa364c7ac6e22bf557cf9792af
tree57db1fa2dc44845741a1ac5f8c5704a555435f40
parent785a6bba2ea1a9d808fefefa1954912a2005fbc1
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.02728 seconds and 4 git commands to generate.