- return trace_names;
-}
-
-/* Helper for ctf_fs_component_create_ctf_fs_traces, to handle a single path/root. */
-
-static
-int ctf_fs_component_create_ctf_fs_traces_one_root(bt_self_component_source *self_comp,
- struct ctf_fs_component *ctf_fs,
- const char *path_param)
-{
- struct ctf_fs_trace *ctf_fs_trace = NULL;
- int ret = 0;
- GString *norm_path = NULL;
- GList *trace_paths = NULL;
- GList *trace_names = NULL;
- GList *tp_node;
- GList *tn_node;
- bt_logging_level log_level = ctf_fs->log_level;
-
- norm_path = bt_common_normalize_path(path_param, NULL);
- if (!norm_path) {
- BT_LOGE("Failed to normalize path: `%s`.",
- path_param);
- goto error;
- }
-
- ret = ctf_fs_find_traces(&trace_paths, norm_path->str, log_level);
- if (ret) {
- goto error;
- }
-
- if (!trace_paths) {
- BT_LOGE("No CTF traces recursively found in `%s`.",
- path_param);
- goto error;
- }
-
- trace_names = ctf_fs_create_trace_names(trace_paths, norm_path->str);
- if (!trace_names) {
- BT_LOGE("Cannot create trace names from trace paths.");
- goto error;
- }
-
- for (tp_node = trace_paths, tn_node = trace_names; tp_node;
- tp_node = g_list_next(tp_node),
- tn_node = g_list_next(tn_node)) {
- GString *trace_path = tp_node->data;
- GString *trace_name = tn_node->data;
-
- ctf_fs_trace = ctf_fs_trace_create(self_comp,
- trace_path->str, trace_name->str,
- &ctf_fs->metadata_config,
- log_level);
- if (!ctf_fs_trace) {
- BT_LOGE("Cannot create trace for `%s`.",
- trace_path->str);
- goto error;
- }
-
- g_ptr_array_add(ctf_fs->traces, ctf_fs_trace);
- ctf_fs_trace = NULL;
- }
-
- goto end;
-
-error:
- ret = -1;
- ctf_fs_trace_destroy(ctf_fs_trace);
-
-end:
- for (tp_node = trace_paths; tp_node; tp_node = g_list_next(tp_node)) {
- if (tp_node->data) {
- g_string_free(tp_node->data, TRUE);
- }
- }
-
- for (tn_node = trace_names; tn_node; tn_node = g_list_next(tn_node)) {
- if (tn_node->data) {
- g_string_free(tn_node->data, TRUE);
- }
- }
-
- if (trace_paths) {
- g_list_free(trace_paths);
- }
-
- if (trace_names) {
- g_list_free(trace_names);
- }
-
- if (norm_path) {
- g_string_free(norm_path, TRUE);
- }
-
- return ret;
-}
-
-/* GCompareFunc to sort traces by UUID. */
-
-static
-gint sort_traces_by_uuid(gconstpointer a, gconstpointer b)
-{
- const struct ctf_fs_trace *trace_a = *((const struct ctf_fs_trace **) a);
- const struct ctf_fs_trace *trace_b = *((const struct ctf_fs_trace **) b);
-
- bool trace_a_has_uuid = trace_a->metadata->tc->is_uuid_set;
- bool trace_b_has_uuid = trace_b->metadata->tc->is_uuid_set;
- gint ret;
-
- /* Order traces without uuid first. */
- if (!trace_a_has_uuid && trace_b_has_uuid) {
- ret = -1;
- } else if (trace_a_has_uuid && !trace_b_has_uuid) {
- ret = 1;
- } else if (!trace_a_has_uuid && !trace_b_has_uuid) {
- ret = 0;
- } else {
- ret = bt_uuid_compare(trace_a->metadata->tc->uuid, trace_b->metadata->tc->uuid);
- }
-
- return ret;
-}
-
-/*
- * Count the number of stream and event classes defined by this trace's metadata.
- *
- * This is used to determine which metadata is the "latest", out of multiple
- * traces sharing the same UUID. It is assumed that amongst all these metadatas,
- * a bigger metadata is a superset of a smaller metadata. Therefore, it is
- * enough to just count the classes.
- */
-
-static
-unsigned int metadata_count_stream_and_event_classes(struct ctf_fs_trace *trace)
-{
- unsigned int num = trace->metadata->tc->stream_classes->len;
- guint i;
-
- for (i = 0; i < trace->metadata->tc->stream_classes->len; i++) {
- struct ctf_stream_class *sc = trace->metadata->tc->stream_classes->pdata[i];
- num += sc->event_classes->len;
- }
-
- return num;
-}
-
-/*
- * Merge the src ds_file_group into dest. This consists of merging their
- * ds_file_infos, making sure to keep the result sorted.
- */
-
-static
-void merge_ctf_fs_ds_file_groups(struct ctf_fs_ds_file_group *dest, struct ctf_fs_ds_file_group *src)
-{
- guint i;
-
- for (i = 0; i < src->ds_file_infos->len; i++) {
- struct ctf_fs_ds_file_info *ds_file_info =
- g_ptr_array_index(src->ds_file_infos, i);
-
- /* Ownership of the ds_file_info is transferred to dest. */
- g_ptr_array_index(src->ds_file_infos, i) = NULL;
-
- ds_file_group_insert_ds_file_info_sorted(dest, ds_file_info);
- }
-
- /* Merge both indexes. */
- for (i = 0; i < src->index->entries->len; i++) {
- struct ctf_fs_ds_index_entry *entry = g_ptr_array_index(
- src->index->entries, i);
-
- /*
- * Ownership of the ctf_fs_ds_index_entry is transferred to
- * dest.
- */
- g_ptr_array_index(src->index->entries, i) = NULL;
-
- ds_file_group_insert_ds_index_entry_sorted(dest, entry);
- }
-}
-/* Merge src_trace's data stream file groups into dest_trace's. */
-
-static
-int merge_matching_ctf_fs_ds_file_groups(
- struct ctf_fs_trace *dest_trace,
- struct ctf_fs_trace *src_trace)
-{
-
- GPtrArray *dest = dest_trace->ds_file_groups;
- GPtrArray *src = src_trace->ds_file_groups;
- guint s_i;
- int ret = 0;
-
- /*
- * Save the initial length of dest: we only want to check against the
- * original elements in the inner loop.
- */
- const guint dest_len = dest->len;
-
- for (s_i = 0; s_i < src->len; s_i++) {
- struct ctf_fs_ds_file_group *src_group = g_ptr_array_index(src, s_i);
- struct ctf_fs_ds_file_group *dest_group = NULL;
-
- /* A stream instance without ID can't match a stream in the other trace. */
- if (src_group->stream_id != -1) {
- guint d_i;
-
- /* Let's search for a matching ds_file_group in the destination. */
- for (d_i = 0; d_i < dest_len; d_i++) {
- struct ctf_fs_ds_file_group *candidate_dest = g_ptr_array_index(dest, d_i);