lib: make can_seek_ns_from_origin logic use `can_seek_forward` property of iterator
[babeltrace.git] / src / plugins / ctf / fs-src / fs.c
index 65d62f96e3b2fdbe117fb8c597a19b4be608c287..08d2acfb9581286724199b56c430a6a40c58bd63 100644 (file)
@@ -248,15 +248,16 @@ void ctf_fs_iterator_finalize(bt_self_message_iterator *it)
 }
 
 BT_HIDDEN
-bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
+bt_component_class_message_iterator_initialize_method_status ctf_fs_iterator_init(
                bt_self_message_iterator *self_msg_iter,
+               bt_self_message_iterator_configuration *config,
                bt_self_component_source *self_comp_src,
                bt_self_component_port_output *self_port)
 {
        struct ctf_fs_port_data *port_data;
        struct ctf_fs_msg_iter_data *msg_iter_data = NULL;
-       bt_component_class_message_iterator_init_method_status ret =
-               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+       bt_component_class_message_iterator_initialize_method_status ret =
+               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK;
        bt_logging_level log_level;
        bt_self_component *self_comp =
                bt_self_component_source_as_self_component(self_comp_src);
@@ -268,7 +269,7 @@ bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
        log_level = port_data->ctf_fs->log_level;
        msg_iter_data = g_new0(struct ctf_fs_msg_iter_data, 1);
        if (!msg_iter_data) {
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -282,22 +283,30 @@ bt_component_class_message_iterator_init_method_status ctf_fs_iterator_init(
                self_comp);
        if (!msg_iter_data->msg_iter) {
                BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create a CTF message iterator.");
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
        msg_iter_data->ds_file_group = port_data->ds_file_group;
        if (ctf_fs_iterator_reset(msg_iter_data)) {
-               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
+               ret = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_ERROR;
                goto error;
        }
 
+       /*
+        * This iterator can seek forward if its stream class has a default
+        * clock class.
+        */
+       if (msg_iter_data->ds_file_group->sc->default_clock_class) {
+               bt_self_message_iterator_configuration_set_can_seek_forward(
+                       config, true);
+       }
+
        bt_self_message_iterator_set_data(self_msg_iter,
                msg_iter_data);
-       if (ret != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK) {
+       if (ret != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INITIALIZE_METHOD_STATUS_OK) {
                goto error;
        }
-
        msg_iter_data = NULL;
        goto end;
 
@@ -1097,6 +1106,7 @@ static
 int ctf_fs_component_create_ctf_fs_trace_one_path(
                struct ctf_fs_component *ctf_fs,
                const char *path_param,
+               const char *trace_name,
                GPtrArray *traces,
                bt_self_component *self_comp,
                bt_self_component_class *self_comp_class)
@@ -1133,7 +1143,7 @@ int ctf_fs_component_create_ctf_fs_trace_one_path(
        }
 
        ctf_fs_trace = ctf_fs_trace_create(self_comp, norm_path->str,
-               norm_path->str, &ctf_fs->metadata_config, log_level);
+               trace_name, &ctf_fs->metadata_config, log_level);
        if (!ctf_fs_trace) {
                BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Cannot create trace for `%s`.",
                        norm_path->str);
@@ -1968,9 +1978,26 @@ end:
        return ret;
 }
 
+static
+gint compare_ds_file_groups_by_first_path(gconstpointer a, gconstpointer b)
+{
+       struct ctf_fs_ds_file_group * const *ds_file_group_a = a;
+       struct ctf_fs_ds_file_group * const *ds_file_group_b = b;
+       const struct ctf_fs_ds_file_info *first_ds_file_info_a;
+       const struct ctf_fs_ds_file_info *first_ds_file_info_b;
+
+       BT_ASSERT((*ds_file_group_a)->ds_file_infos->len > 0);
+       BT_ASSERT((*ds_file_group_b)->ds_file_infos->len > 0);
+       first_ds_file_info_a = (*ds_file_group_a)->ds_file_infos->pdata[0];
+       first_ds_file_info_b = (*ds_file_group_b)->ds_file_infos->pdata[0];
+       return strcmp(first_ds_file_info_a->path->str,
+               first_ds_file_info_b->path->str);
+}
+
 int ctf_fs_component_create_ctf_fs_trace(
                struct ctf_fs_component *ctf_fs,
                const bt_value *paths_value,
+               const bt_value *trace_name_value,
                bt_self_component *self_comp,
                bt_self_component_class *self_comp_class)
 {
@@ -1978,6 +2005,7 @@ int ctf_fs_component_create_ctf_fs_trace(
        uint64_t i;
        bt_logging_level log_level = ctf_fs->log_level;
        GPtrArray *traces;
+       const char *trace_name;
 
        BT_ASSERT(bt_value_get_type(paths_value) == BT_VALUE_TYPE_ARRAY);
        BT_ASSERT(!bt_value_array_is_empty(paths_value));
@@ -1989,13 +2017,15 @@ int ctf_fs_component_create_ctf_fs_trace(
                goto error;
        }
 
+       trace_name = trace_name_value ? bt_value_string_get(trace_name_value) : NULL;
+
        /* Start by creating a separate ctf_fs_trace object for each path. */
        for (i = 0; i < bt_value_array_get_length(paths_value); i++) {
                const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i);
                const char *input = bt_value_string_get(path_value);
 
                ret = ctf_fs_component_create_ctf_fs_trace_one_path(ctf_fs,
-                       input, traces, self_comp, self_comp_class);
+                       input, trace_name, traces, self_comp, self_comp_class);
                if (ret) {
                        goto end;
                }
@@ -2060,6 +2090,20 @@ int ctf_fs_component_create_ctf_fs_trace(
                        "Failed to fix packet index tracer bugs.");
        }
 
+       /*
+        * Sort data stream file groups by first data stream file info
+        * path to get a deterministic order. This order influences the
+        * order of the output ports. It also influences the order of
+        * the automatic stream IDs if the trace's packet headers do not
+        * contain a `stream_instance_id` field, in which case the data
+        * stream file to stream ID association is always the same,
+        * whatever the build and the system.
+        *
+        * Having a deterministic order here can help debugging and
+        * testing.
+        */
+       g_ptr_array_sort(ctf_fs->trace->ds_file_groups,
+               compare_ds_file_groups_by_first_path);
        goto end;
 error:
        ret = -1;
@@ -2229,7 +2273,9 @@ end:
 }
 
 bool read_src_fs_parameters(const bt_value *params,
-               const bt_value **inputs, struct ctf_fs_component *ctf_fs,
+               const bt_value **inputs,
+               const bt_value **trace_name,
+               struct ctf_fs_component *ctf_fs,
                bt_self_component *self_comp,
                bt_self_component_class *self_comp_class) {
        bool ret;
@@ -2268,6 +2314,29 @@ bool read_src_fs_parameters(const bt_value *params,
                        bt_value_integer_signed_get(value);
        }
 
+       /* force-clock-class-origin-unix-epoch parameter */
+       value = bt_value_map_borrow_entry_value_const(params,
+               "force-clock-class-origin-unix-epoch");
+       if (value) {
+               if (!bt_value_is_bool(value)) {
+                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
+                               "force-clock-class-origin-unix-epoch must be a boolean");
+                       goto error;
+               }
+
+               ctf_fs->metadata_config.force_clock_class_origin_unix_epoch =
+                       bt_value_bool_get(value);
+       }
+
+       /* trace-name parameter */
+       *trace_name = bt_value_map_borrow_entry_value_const(params, "trace-name");
+       if (*trace_name) {
+               if (!bt_value_is_string(*trace_name)) {
+                       BT_COMP_OR_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp, self_comp_class,
+                               "trace-name must be a string");
+                       goto error;
+               }
+       }
 
        ret = true;
        goto end;
@@ -2287,6 +2356,7 @@ struct ctf_fs_component *ctf_fs_create(
 {
        struct ctf_fs_component *ctf_fs = NULL;
        const bt_value *inputs_value;
+       const bt_value *trace_name_value;
        bt_self_component *self_comp =
                bt_self_component_source_as_self_component(self_comp_src);
 
@@ -2296,15 +2366,15 @@ struct ctf_fs_component *ctf_fs_create(
                goto error;
        }
 
-       if (!read_src_fs_parameters(params, &inputs_value, ctf_fs,
-                       self_comp, self_comp_class)) {
+       if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value,
+                       ctf_fs, self_comp, self_comp_class)) {
                goto error;
        }
 
        bt_self_component_set_data(self_comp, ctf_fs);
 
        if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value,
-                       self_comp, self_comp_class)) {
+                       trace_name_value, self_comp, self_comp_class)) {
                goto error;
        }
 
@@ -2328,17 +2398,18 @@ end:
 }
 
 BT_HIDDEN
-bt_component_class_init_method_status ctf_fs_init(
+bt_component_class_initialize_method_status ctf_fs_init(
                bt_self_component_source *self_comp_src,
+               bt_self_component_source_configuration *config,
                const bt_value *params, __attribute__((unused)) void *init_method_data)
 {
        struct ctf_fs_component *ctf_fs;
-       bt_component_class_init_method_status ret =
-               BT_COMPONENT_CLASS_INIT_METHOD_STATUS_OK;
+       bt_component_class_initialize_method_status ret =
+               BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
 
        ctf_fs = ctf_fs_create(params, self_comp_src, NULL);
        if (!ctf_fs) {
-               ret = BT_COMPONENT_CLASS_INIT_METHOD_STATUS_ERROR;
+               ret = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
        }
 
        return ret;
@@ -2361,8 +2432,8 @@ bt_component_class_query_method_status ctf_fs_query(
        if (strcmp(object, "metadata-info") == 0) {
                status = metadata_info_query(comp_class, params, log_level,
                        result);
-       } else if (strcmp(object, "babeltrace.trace-info") == 0) {
-               status = trace_info_query(comp_class, params, log_level,
+       } else if (strcmp(object, "babeltrace.trace-infos") == 0) {
+               status = trace_infos_query(comp_class, params, log_level,
                        result);
        } else if (!strcmp(object, "babeltrace.support-info")) {
                status = support_info_query(comp_class, params, log_level, result);
This page took 0.026807 seconds and 4 git commands to generate.