lib: add unsigned and signed integer value API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 3 May 2019 19:14:18 +0000 (15:14 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 6 May 2019 14:13:09 +0000 (10:13 -0400)
commitfdd3a2da18afef5ca32ba181a8b6ebbff173df02
treeaa89e9901b6386ef313879fa15734393ca8efa3b
parent11cd69be12a8f694b9ddc9b8d8cc6936b7f51596
lib: add unsigned and signed integer value API

This patch replaces the integer value API with the more specific
unsigned and signed integer value API. This opens the whole unsigned
64-bit set for component initialization parameters, query parameters,
queyr results, and, eventually, custom metadata attributes. This is also
more in line with the field API, which has both the unsigned and signed
versions.

Library
=======
The API is simply split in two, where an unsigned integer value contains
a `uint64_t` raw value and a signed integer value is the equivalent of
the previous integer value (`int64_t` raw value).

The types are `BT_VALUE_TYPE_UNSIGNED_INTEGER` and
`BT_VALUE_TYPE_SIGNED_INTEGER`.

There's no interaction between unsigned and signed integer values, in
that, for example, you cannot compare an unsigned integer value with a
signed integer value with bt_value_compare().

Behind the scenes, I kept a single `struct bt_value_integer` for
simplicity. It contains a union of `uint64_t` and `int64_t`. Most
functions call a generic unsigned version, casting to `uint64_t` when
necessary. For example, there's a common bt_value_integer_compare()
which compares the `uint64_t` values.

CLI
===
Before this patch, the `--params` option's format makes any integer
constant a signed integer value object. With this patch, you can create
an unsigned integer value by prepending the constant with `+`. For
example:

    hello=+293, meow=+0x388ab88fd, uint-zero=+0

I wanted to use the `U` suffix, like in C/C++, but the GLib lexical
scanner won't allow a constant to be followed by an identifier without a
whitespace.

The documentation about the format of `--params` is updated for the
CLI's `--help` option and in the man pages.

Plugins
=======
It's up to each plugin to accept, for a given parameter, an unsigned
integer value, a signed integer value, or both. A plugin can be very
strict and it's not a bad thing: there are situations where an unsigned
integer is conceptually required.

The individual changes are:

`src.ctf.fs`:
    In the `trace-info` query result, create unsigned integer values for
    the `id` (stream ID) and `class-id` (stream class ID) entries. A CTF
    metadata ID is never negative.

`src.ctf.lttng-live`:
    In the `sessions` query result, the `timer-us`, `stream-count`, and
    `client-count` entries are still signed integer values. They could
    probably be unsigned, but I want to confirm this with developers
    more involved with this component class before doing the change. For
    the moment, the query operation is unchanged.

`sink.utils.counter`:
    The `step` initialization parameter is now expected to be an
    unsigned integer value. This is never negative.

    I also made the initialization refuse parameters when they don't
    have the expected type. There are new `logging.c` and `logging.h`
    files for this component class because I used logging to communicate
    said errors.

Library tests
=============
The integer value tests now test the signed value API.

I added equivalent unsigned value object tests.

Python bindings
===============
`_IntegerValue` is now the base class of `UnsignedIntegerValue` and
`SignedIntegerValue`. `_IntegerValue` contains the whole public
interface, using template methods with specialized parts defined in
subclasses.

`_IntegerValue` is imported in the `bt2` package for this use case:

    if isinstance(val, bt2._IntegerValue):
        do_something_with(val)

because `int(val)` is always valid.

The bt2.create_value() function still creates a `SignedIntegerValue`
object with an `int` value. This is the safest, as there's no way to
know that this value will be changed to a negative value in the future,
before the value object is frozen. For example, this would not be
possible with a conversion to an `UnsignedIntegerValue`:

    val = bt2.create_value(47)
    val.value = -23

whereas it is possible with a `SignedIntegerValue`. You can still
explicitly create an unsigned integer value:

    counter_comp = my_graph.add_component(counter_cls, 'counter', {
        'step': bt2.UnsignedIntegerValue(29)
    });

Python bindings tests
=====================
`test_value.py` is updated to also test the `UnsignedIntegerValue`
class. _inject_numeric_testing_methods() now accepts an optional
`has_neg` parameter which, if false, does not inject tests which involve
negative integer values.

There is a common `_TestIntegerValue` class which
`SignedIntegerValueTestCase` and `UnsignedIntegerValueTestCase` inherit.
The tests are almost the same, but `SignedIntegerValueTestCase` adds a
few tests related to negative values. Both specific test cases set the
`_CLS` class attribute to the value object class to test, either
`UnsignedIntegerValue` or `SignedIntegerValue`.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ic96ef9e1e16883cb5c59844c6ba5a060936efdb0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1257
Tested-by: jenkins
29 files changed:
bindings/python/bt2/bt2/__init__.py.in
bindings/python/bt2/bt2/native_bt_value.i
bindings/python/bt2/bt2/value.py
cli/babeltrace-cfg-cli-args.c
cli/babeltrace.c
doc/man/common-cmd-params-format.txt
include/babeltrace/common-internal.h
include/babeltrace/value-const.h
include/babeltrace/value-internal.h
include/babeltrace/value.h
lib/lib-logging.c
lib/trace-ir/trace-class.c
lib/value.c
plugins/ctf/fs-sink/fs-sink-trace.c
plugins/ctf/fs-sink/translate-ctf-ir-to-tsdl.c
plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c
plugins/ctf/fs-src/fs.c
plugins/ctf/fs-src/query.c
plugins/ctf/lttng-live/viewer-connection.c
plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c
plugins/text/pretty/print.c
plugins/utils/counter/Makefile.am
plugins/utils/counter/counter.c
plugins/utils/counter/logging.c [new file with mode: 0644]
plugins/utils/counter/logging.h [new file with mode: 0644]
plugins/utils/trimmer/trimmer.c
tests/bindings/python/bt2/test_value.py
tests/lib/test_bt_values.c
tests/lib/test_plugin.c
This page took 0.027651 seconds and 4 git commands to generate.