lib: add seeking (beginning, ns from origin), with auto-seeking support
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 16 Jan 2019 22:19:14 +0000 (17:19 -0500)
committerFrancis Deslauriers <francis.deslauriers@efficios.com>
Thu, 2 May 2019 20:50:15 +0000 (20:50 +0000)
commit7474e7d3f0d005280c6614be5c818735e65d8b3b
treecfe08f7bbdb308ac3a1436a68b1b1cbb3946b1ea
parent4725a2013cb518374822ccb490610b45f74dbdbf
lib: add seeking (beginning, ns from origin), with auto-seeking support

This patch adds seeking support to the message iterator API. Two seeking
operations are supported:

Seek beginning:
    The message iterator goes back to the beginning, that is, to its
    first message (which is probably a "stream beginning" message).

Seek nanoseconds from origin:
    The message iterator seeks a message which has a default clock
    snapshot which is at least the requested value when converted to
    nanoseconds from epoch.

    No clock class is involved in this operation, only a plain value in
    nanoseconds from an origin (which can be negative), to support
    seeking through an iterator chain with multiple clock classes
    involved. What a message iterator should do exactly is left to the
    implementation for more flexibility.

A source or filter component class can have four new optional message
iterator methods:

Can seek beginning:
    Returns whether or not it is possible for this iterator to seek its
    beginning.

    If not set, the corresponding API functions
    (bt_self_component_port_input_message_iterator_can_seek_beginning()
    and bt_port_output_message_iterator_can_seek_beginning()) return:

    * `BT_TRUE` if the "seek beginning" method (see below) is set.
    * `BT_FALSE` otherwise.

Can seek nanoseconds from origin:
    Returns whether or not it is possible for this iterator to seek a
    given nanosecond from origin.

    If not set, the corresponding API functions
    (bt_self_component_port_input_message_iterator_can_seek_ns_from_origin()
    and bt_port_output_message_iterator_can_seek_ns_from_origin())
    return:

    * `BT_TRUE` if the "seek nanoseconds from origin" method (see below)
       is set, or if
       bt_self_component_port_input_message_iterator_can_seek_beginning()
       returns `BT_TRUE` (auto-seeking, see below).
    * `BT_FALSE` otherwise.

Seek beginning:
    Seeks this iterator to its beginning.

    The corresponding API functions are
    bt_self_component_port_input_message_iterator_seek_beginning() and
    bt_port_output_message_iterator_seek_beginning().

Seek nanoseconds from origin:
    Seeks this iterator to a specific nanosecond from origin.

    The corresponding API functions are
    bt_self_component_port_input_message_iterator_seek_ns_from_origin()
    and bt_port_output_message_iterator_seek_ns_from_origin().

    If not set, then if
    bt_self_component_port_input_message_iterator_can_seek_beginning()
    returns `BT_TRUE` (which means it is possible for this iterator to
    seek its beginning) for this iterator, then auto-seeking is enabled
    for this iterator.

Auto-seeking is a feature which makes the library use only the "seek
beginning" method of an iterator to implement a "seek nanoseconds from
origin" method which calls the iterator's "next" method, skipping
messages until it finds one which matches the requested value. This
exists because most of the time it is easier for a plugin developer to
reset an iterator's state to the beginning than to seek a message having
a specific clock snapshot value.

With the conditions described above:

* If you implement the "seek beginning" method, it is the equivalent of
  also implementing a "can seek beginning" method which always returns
  `BT_TRUE`.

* If you implement the "seek nanoseconds from origin" method, it is the
  equivalent of also implementing a "can seek nanoseconds from origin"
  method which always returns `BT_TRUE`.

* If you only implement the "seek beginning" method, than the iterator's
  user can always seek beginning and any nanosecond from origin.

* If you implement none of the above methods, then seeking is completely
  disabled.

The methods, as well as the corresponding API functions, can return the
following message iterator statuses:

`BT_SELF_MESSAGE_ITERATOR_STATUS_OK`:
    The seeking operation succeeded.

    This is the only status which allows a subsequent call to the
    iterator's "next" method.

`BT_SELF_MESSAGE_ITERATOR_STATUS_AGAIN`:
    The seeking operation did not terminate, but this is not an error:
    the iterator's user should seek again later (the same time or
    a different time, for example you can seek beginning after getting
    this status from seeking a specific nanosecond from origin).

`BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR`:
`BT_SELF_MESSAGE_ITERATOR_STATUS_NOMEM`:
    The seeking operation failed: the iterator's user must seek again
    (with success) in order to make the iterator active again (able to
    advance).

The seeking methods cannot return `BT_SELF_MESSAGE_ITERATOR_STATUS_END`:
if seeking reaches the end, then the seeking method must return
`BT_SELF_MESSAGE_ITERATOR_STATUS_OK` and the following call to its
"next" method must return `BT_SELF_MESSAGE_ITERATOR_STATUS_END`.

After a successful seeking operation, the first message of the batch
that an iterator's "next" method returns can be of ANY type. Therefore,
an iterator's user must have its state ready when seeking because the
usual guarantees do not need to be satisfied (for example, getting a
"packet beginning" message before any event message).

Because seeking breaks the concept of having contiguous messages with no
interruption, the concept of a message's sequence number for developer
mode validation is removed. We need to find another way to make this
validation in the future.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
21 files changed:
include/Makefile.am
include/babeltrace/babeltrace.h
include/babeltrace/graph/component-class-filter.h
include/babeltrace/graph/component-class-internal.h
include/babeltrace/graph/component-class-sink-colander-internal.h
include/babeltrace/graph/component-class-source.h
include/babeltrace/graph/connection-internal.h
include/babeltrace/graph/message-internal.h
include/babeltrace/graph/message-iterator-const.h [new file with mode: 0644]
include/babeltrace/graph/message-iterator-internal.h
include/babeltrace/graph/message-iterator.h [deleted file]
include/babeltrace/graph/port-output-message-iterator.h
include/babeltrace/graph/self-component-port-input-message-iterator.h
include/babeltrace/graph/self-message-iterator.h
include/babeltrace/plugin/plugin-dev.h
lib/graph/component-class-sink-colander.c
lib/graph/component-class.c
lib/graph/component-source.c
lib/graph/iterator.c
lib/graph/message/message.c
lib/plugin/plugin-so.c
This page took 0.028345 seconds and 4 git commands to generate.