Rename: field type -> field class
[babeltrace.git] / plugins / ctf / common / metadata / ctf-meta-update-in-ir.c
CommitLineData
44c440bc
PP
1/*
2 * Copyright 2018 - Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 */
14
15#define BT_LOG_TAG "PLUGIN-CTF-METADATA-META-UPDATE-IN-IR"
16#include "logging.h"
17
18#include <babeltrace/babeltrace.h>
19#include <babeltrace/babeltrace-internal.h>
20#include <babeltrace/assert-internal.h>
21#include <babeltrace/compat/glib-internal.h>
22#include <glib.h>
23#include <stdint.h>
24#include <string.h>
25#include <inttypes.h>
26
27#include "ctf-meta-visitors.h"
28
29static
5cd6d0e5 30void update_field_class_in_ir(struct ctf_field_class *fc,
44c440bc
PP
31 GHashTable *ft_dependents)
32{
33 int64_t i;
34
5cd6d0e5 35 if (!fc) {
44c440bc
PP
36 goto end;
37 }
38
5cd6d0e5
PP
39 switch (fc->id) {
40 case CTF_FIELD_CLASS_ID_INT:
41 case CTF_FIELD_CLASS_ID_ENUM:
44c440bc 42 {
5cd6d0e5 43 struct ctf_field_class_int *int_fc = (void *) fc;
44c440bc 44
5cd6d0e5
PP
45 if (int_fc->mapped_clock_class ||
46 int_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE ||
47 bt_g_hash_table_contains(ft_dependents, fc)) {
44c440bc 48 /*
5cd6d0e5 49 * Field class does not update a clock, has no
44c440bc 50 * special meaning, and no sequence/variant
5cd6d0e5 51 * field class which is part of IR depends on it.
44c440bc 52 */
5cd6d0e5 53 fc->in_ir = true;
44c440bc
PP
54 }
55
56 break;
57 }
5cd6d0e5 58 case CTF_FIELD_CLASS_ID_STRUCT:
44c440bc 59 {
5cd6d0e5 60 struct ctf_field_class_struct *struct_fc = (void *) fc;
44c440bc
PP
61
62 /* Reverse order */
5cd6d0e5
PP
63 for (i = (int64_t) struct_fc->members->len - 1; i >= 0; i--) {
64 struct ctf_named_field_class *named_fc =
65 ctf_field_class_struct_borrow_member_by_index(
66 struct_fc, i);
44c440bc 67
5cd6d0e5 68 update_field_class_in_ir(named_fc->fc, ft_dependents);
44c440bc 69
5cd6d0e5 70 if (named_fc->fc->in_ir) {
44c440bc 71 /* At least one member is part of IR */
5cd6d0e5 72 fc->in_ir = true;
44c440bc
PP
73 }
74 }
75
76 break;
77 }
5cd6d0e5 78 case CTF_FIELD_CLASS_ID_VARIANT:
44c440bc 79 {
5cd6d0e5
PP
80 struct ctf_named_field_class *named_fc;
81 struct ctf_field_class_variant *var_fc = (void *) fc;
44c440bc
PP
82
83 /*
84 * Reverse order, although it is not important for this
5cd6d0e5
PP
85 * loop because a field class within a variant field
86 * type's option cannot depend on a field class in
87 * another option of the same variant field class.
44c440bc 88 */
5cd6d0e5
PP
89 for (i = (int64_t) var_fc->options->len - 1; i >= 0; i--) {
90 named_fc =
91 ctf_field_class_variant_borrow_option_by_index(
92 var_fc, i);
44c440bc 93
5cd6d0e5 94 update_field_class_in_ir(named_fc->fc, ft_dependents);
44c440bc 95
5cd6d0e5 96 if (named_fc->fc->in_ir) {
44c440bc 97 /* At least one option is part of IR */
5cd6d0e5 98 fc->in_ir = true;
44c440bc
PP
99 }
100 }
101
5cd6d0e5 102 if (fc->in_ir) {
44c440bc
PP
103 /*
104 * At least one option will make it to IR. In
105 * this case, make all options part of IR
106 * because the variant's tag could still select
107 * (dynamically) a removed option. This can mean
108 * having an empty structure as an option, for
109 * example, but at least all the options are
110 * selectable.
111 */
5cd6d0e5
PP
112 for (i = 0; i < var_fc->options->len; i++) {
113 ctf_field_class_variant_borrow_option_by_index(
114 var_fc, i)->fc->in_ir = true;
44c440bc
PP
115 }
116
117 /*
5cd6d0e5
PP
118 * This variant field class is part of IR and
119 * depends on a tag field class (which must also
44c440bc
PP
120 * be part of IR).
121 */
5cd6d0e5
PP
122 g_hash_table_insert(ft_dependents, var_fc->tag_fc,
123 var_fc->tag_fc);
44c440bc
PP
124 }
125
126 break;
127 }
5cd6d0e5
PP
128 case CTF_FIELD_CLASS_ID_ARRAY:
129 case CTF_FIELD_CLASS_ID_SEQUENCE:
44c440bc 130 {
5cd6d0e5 131 struct ctf_field_class_array_base *array_fc = (void *) fc;
44c440bc 132
5cd6d0e5
PP
133 update_field_class_in_ir(array_fc->elem_fc, ft_dependents);
134 fc->in_ir = array_fc->elem_fc->in_ir;
44c440bc 135
5cd6d0e5
PP
136 if (fc->id == CTF_FIELD_CLASS_ID_ARRAY) {
137 struct ctf_field_class_array *arr_fc = (void *) fc;
44c440bc 138
5cd6d0e5
PP
139 assert(arr_fc->meaning == CTF_FIELD_CLASS_MEANING_NONE ||
140 arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID);
44c440bc
PP
141
142 /*
5cd6d0e5 143 * UUID field class: nothing depends on this, so
44c440bc
PP
144 * it's not part of IR.
145 */
5cd6d0e5
PP
146 if (arr_fc->meaning == CTF_FIELD_CLASS_MEANING_UUID) {
147 fc->in_ir = false;
148 array_fc->elem_fc->in_ir = false;
44c440bc 149 }
5cd6d0e5
PP
150 } else if (fc->id == CTF_FIELD_CLASS_ID_SEQUENCE) {
151 if (fc->in_ir) {
152 struct ctf_field_class_sequence *seq_fc = (void *) fc;
44c440bc
PP
153
154 /*
5cd6d0e5
PP
155 * This sequence field class is part of
156 * IR and depends on a length field class
44c440bc
PP
157 * (which must also be part of IR).
158 */
159 g_hash_table_insert(ft_dependents,
5cd6d0e5 160 seq_fc->length_fc, seq_fc->length_fc);
44c440bc
PP
161 }
162 }
163
164 break;
165 }
166 default:
5cd6d0e5 167 fc->in_ir = true;
44c440bc
PP
168 break;
169 }
170
171end:
172 return;
173}
174
175/*
5cd6d0e5
PP
176 * Scopes and field classes are processed in reverse order because we need
177 * to know if a given integer field class has dependents (sequence or
178 * variant field classes) when we reach it. Dependents can only be located
179 * after the length/tag field class in the metadata tree.
44c440bc
PP
180 */
181BT_HIDDEN
182int ctf_trace_class_update_in_ir(struct ctf_trace_class *ctf_tc)
183{
184 int ret = 0;
185 uint64_t i;
186
187 GHashTable *ft_dependents = g_hash_table_new(g_direct_hash,
188 g_direct_equal);
189
190 BT_ASSERT(ft_dependents);
191
192 for (i = 0; i < ctf_tc->stream_classes->len; i++) {
193 struct ctf_stream_class *sc = ctf_tc->stream_classes->pdata[i];
194 uint64_t j;
195
196 for (j = 0; j < sc->event_classes->len; j++) {
197 struct ctf_event_class *ec = sc->event_classes->pdata[j];
198
199 if (ec->is_translated) {
200 continue;
201 }
202
5cd6d0e5
PP
203 update_field_class_in_ir(ec->payload_fc, ft_dependents);
204 update_field_class_in_ir(ec->spec_context_fc,
44c440bc
PP
205 ft_dependents);
206 }
207
208 if (!sc->is_translated) {
5cd6d0e5 209 update_field_class_in_ir(sc->event_common_context_fc,
44c440bc 210 ft_dependents);
5cd6d0e5 211 update_field_class_in_ir(sc->event_header_fc,
44c440bc 212 ft_dependents);
5cd6d0e5 213 update_field_class_in_ir(sc->packet_context_fc,
44c440bc
PP
214 ft_dependents);
215 }
216 }
217
218 if (!ctf_tc->is_translated) {
5cd6d0e5 219 update_field_class_in_ir(ctf_tc->packet_header_fc,
44c440bc
PP
220 ft_dependents);
221 }
222
223 g_hash_table_destroy(ft_dependents);
224 return ret;
225}
This page took 0.03365 seconds and 4 git commands to generate.