Fix -Wmissing-prototypes/-Wmissing-declarations warnings
[babeltrace.git] / src / lib / integer-range-set.c
CommitLineData
ba38aae7
PP
1/*
2 * Copyright 2019 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 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#define BT_LOG_TAG "LIB/INT-RANGE-SET"
24#include "lib/logging.h"
25
26#include <babeltrace2/babeltrace.h>
27#include "lib/assert-pre.h"
28#include "common/assert.h"
29#include "func-status.h"
30#include "integer-range-set.h"
31
88efd0a7
PP
32uint64_t bt_integer_range_unsigned_get_lower(
33 const struct bt_integer_range_unsigned *u_range)
ba38aae7
PP
34{
35 const struct bt_integer_range *range = (const void *) u_range;
36
88efd0a7 37 BT_ASSERT_PRE_DEV_NON_NULL(range, "Integer range");
ba38aae7
PP
38 return range->lower.u;
39}
40
88efd0a7
PP
41uint64_t bt_integer_range_unsigned_get_upper(
42 const struct bt_integer_range_unsigned *u_range)
ba38aae7
PP
43{
44 const struct bt_integer_range *range = (const void *) u_range;
45
88efd0a7 46 BT_ASSERT_PRE_DEV_NON_NULL(range, "Integer range");
ba38aae7
PP
47 return range->upper.u;
48}
49
88efd0a7
PP
50int64_t bt_integer_range_signed_get_lower(
51 const struct bt_integer_range_signed *i_range)
ba38aae7
PP
52{
53 const struct bt_integer_range *range = (const void *) i_range;
54
88efd0a7 55 BT_ASSERT_PRE_DEV_NON_NULL(range, "Integer range");
ba38aae7
PP
56 return range->lower.i;
57}
58
88efd0a7
PP
59int64_t bt_integer_range_signed_get_upper(
60 const struct bt_integer_range_signed *i_range)
ba38aae7
PP
61{
62 const struct bt_integer_range *range = (const void *) i_range;
63
88efd0a7 64 BT_ASSERT_PRE_DEV_NON_NULL(range, "Integer range");
ba38aae7
PP
65 return range->upper.i;
66}
67
68static
69bool compare_ranges(const struct bt_integer_range *range_a,
70 const struct bt_integer_range *range_b)
71{
72 return range_a->lower.u == range_b->lower.u &&
73 range_a->upper.u == range_b->upper.u;
74}
75
e1c423f9 76bt_bool bt_integer_range_unsigned_is_equal(
ba38aae7
PP
77 const struct bt_integer_range_unsigned *range_a,
78 const struct bt_integer_range_unsigned *range_b)
79{
88efd0a7
PP
80 BT_ASSERT_PRE_DEV_NON_NULL(range_a, "Integer range A");
81 BT_ASSERT_PRE_DEV_NON_NULL(range_b, "Integer range B");
ba38aae7
PP
82 return (bt_bool) compare_ranges((const void *) range_a,
83 (const void *) range_b);
84}
85
e1c423f9 86bt_bool bt_integer_range_signed_is_equal(
ba38aae7
PP
87 const struct bt_integer_range_signed *range_a,
88 const struct bt_integer_range_signed *range_b)
89{
88efd0a7
PP
90 BT_ASSERT_PRE_DEV_NON_NULL(range_a, "Integer range A");
91 BT_ASSERT_PRE_DEV_NON_NULL(range_b, "Integer range B");
ba38aae7
PP
92 return (bt_bool) compare_ranges((const void *) range_a,
93 (const void *) range_b);
94}
95
96uint64_t bt_integer_range_set_get_range_count(
97 const bt_integer_range_set *range_set)
98{
88efd0a7 99 BT_ASSERT_PRE_DEV_NON_NULL(range_set, "Integer range set");
ba38aae7
PP
100 return (uint64_t) range_set->ranges->len;
101}
102
88efd0a7
PP
103const struct bt_integer_range_unsigned *
104bt_integer_range_set_unsigned_borrow_range_by_index_const(
105 const bt_integer_range_set_unsigned *u_range_set,
106 uint64_t index)
ba38aae7 107{
88efd0a7
PP
108 const struct bt_integer_range_set *range_set =
109 (const void *) u_range_set;
ba38aae7 110
88efd0a7 111 BT_ASSERT_PRE_DEV_NON_NULL(range_set, "Integer range set");
ba38aae7 112 BT_ASSERT_PRE_DEV_VALID_INDEX(index, range_set->ranges->len);
88efd0a7
PP
113 return (const void *) BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set,
114 index);
ba38aae7
PP
115}
116
88efd0a7
PP
117const struct bt_integer_range_signed *
118bt_integer_range_set_signed_borrow_range_by_index_const(
ba38aae7
PP
119 const bt_integer_range_set_signed *i_range_set, uint64_t index)
120{
88efd0a7
PP
121 const struct bt_integer_range_set *range_set =
122 (const void *) i_range_set;
ba38aae7 123
88efd0a7 124 BT_ASSERT_PRE_DEV_NON_NULL(range_set, "Integer range set");
ba38aae7 125 BT_ASSERT_PRE_DEV_VALID_INDEX(index, range_set->ranges->len);
88efd0a7
PP
126 return (const void *) BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set,
127 index);
ba38aae7
PP
128}
129
130static
131void destroy_range_set(struct bt_object *obj)
132{
133 struct bt_integer_range_set *range_set = (void *) obj;
134
88efd0a7
PP
135 BT_LIB_LOGD("Destroying integer range set: %!+R", range_set);
136
ba38aae7
PP
137 if (range_set->ranges) {
138 g_array_free(range_set->ranges, TRUE);
139 range_set->ranges = NULL;
140 }
141
142 g_free(range_set);
143}
144
145static
146struct bt_integer_range_set *create_range_set(void)
147{
88efd0a7
PP
148 struct bt_integer_range_set *range_set;
149
150 BT_LOGD_STR("Creating empty integer range set.");
151 range_set = g_new0(struct bt_integer_range_set, 1);
ba38aae7
PP
152
153 if (!range_set) {
88efd0a7
PP
154 BT_LIB_LOGE_APPEND_CAUSE(
155 "Failed to allocate one integer range set.");
ba38aae7
PP
156 goto error;
157 }
158
159 bt_object_init_shared(&range_set->base, destroy_range_set);
160 range_set->ranges = g_array_new(FALSE, TRUE,
161 sizeof(struct bt_integer_range));
162 if (!range_set->ranges) {
163 BT_LIB_LOGE_APPEND_CAUSE(
88efd0a7 164 "Failed to allocate integer range set's range array.");
ba38aae7
PP
165 goto error;
166 }
167
88efd0a7 168 BT_LOGD_STR("Created empty integer range set.");
ba38aae7
PP
169 goto end;
170
171error:
172 BT_OBJECT_PUT_REF_AND_RESET(range_set);
173
174end:
175 return range_set;
176}
177
178struct bt_integer_range_set_unsigned *bt_integer_range_set_unsigned_create(void)
179{
180 return (void *) create_range_set();
181}
182
183struct bt_integer_range_set_signed *bt_integer_range_set_signed_create(void)
184{
185 return (void *) create_range_set();
186}
187
f3847c75 188static
ba38aae7
PP
189void add_range_to_range_set(struct bt_integer_range_set *range_set,
190 uint64_t u_lower, uint64_t u_upper)
191{
192 struct bt_integer_range range = {
193 .lower.u = u_lower,
194 .upper.u = u_upper,
195 };
196
88efd0a7
PP
197 BT_ASSERT_PRE_NON_NULL(range_set, "Integer range set");
198 BT_ASSERT_PRE_DEV_HOT(range_set, "Integer range set", ": %!+R",
199 range_set);
ba38aae7 200 g_array_append_val(range_set->ranges, range);
88efd0a7
PP
201 BT_LIB_LOGD("Added integer range to integer range set: "
202 "%![range-set-]+R, lower-unsigned=%" PRIu64 ", "
203 "upper-unsigned=%" PRIu64, range_set, u_lower, u_upper);
ba38aae7
PP
204}
205
88efd0a7
PP
206enum bt_integer_range_set_add_range_status
207bt_integer_range_set_unsigned_add_range(
ba38aae7
PP
208 struct bt_integer_range_set_unsigned *range_set,
209 uint64_t lower, uint64_t upper)
210{
211 BT_ASSERT_PRE(lower <= upper,
212 "Range's upper bound is less than lower bound: "
213 "upper=%" PRIu64 ", lower=%" PRIu64, lower, upper);
214 add_range_to_range_set((void *) range_set, lower, upper);
215 return BT_FUNC_STATUS_OK;
216}
217
88efd0a7
PP
218enum bt_integer_range_set_add_range_status
219bt_integer_range_set_signed_add_range(
ba38aae7
PP
220 struct bt_integer_range_set_signed *range_set,
221 int64_t lower, int64_t upper)
222{
223 BT_ASSERT_PRE(lower <= upper,
224 "Range's upper bound is less than lower bound: "
225 "upper=%" PRId64 ", lower=%" PRId64, lower, upper);
226 add_range_to_range_set((void *) range_set,
227 (int64_t) lower, (int64_t) upper);
228 return BT_FUNC_STATUS_OK;
229}
230
231BT_HIDDEN
232void _bt_integer_range_set_freeze(const struct bt_integer_range_set *range_set)
233{
234 BT_ASSERT(range_set);
88efd0a7 235 BT_LIB_LOGD("Freezing integer range set: %!+R", range_set);
ba38aae7
PP
236 ((struct bt_integer_range_set *) range_set)->frozen = true;
237}
238
239BT_HIDDEN
88efd0a7
PP
240bool bt_integer_range_set_unsigned_has_overlaps(
241 const struct bt_integer_range_set *range_set)
ba38aae7
PP
242{
243 uint64_t i, j;
244 bool has_overlap = false;
245
246 BT_ASSERT(range_set);
247
248 for (i = 0; i < range_set->ranges->len; i++) {
249 const struct bt_integer_range *range_i =
250 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set, i);
251
252 for (j = 0; j < range_set->ranges->len; j++) {
253 const struct bt_integer_range *range_j =
88efd0a7
PP
254 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
255 range_set, j);
ba38aae7
PP
256
257 if (i == j) {
258 continue;
259 }
260
261 if (range_i->lower.u <= range_j->upper.u &&
262 range_j->lower.u <= range_i->upper.u) {
263 has_overlap = true;
264 goto end;
265 }
266 }
267 }
268
269end:
270 return has_overlap;
271}
272
273BT_HIDDEN
88efd0a7
PP
274bool bt_integer_range_set_signed_has_overlaps(
275 const struct bt_integer_range_set *range_set)
ba38aae7
PP
276{
277 uint64_t i, j;
278 bool has_overlap = false;
279
280 BT_ASSERT(range_set);
281
282 for (i = 0; i < range_set->ranges->len; i++) {
283 const struct bt_integer_range *range_i =
284 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set, i);
285
286 for (j = 0; j < range_set->ranges->len; j++) {
287 const struct bt_integer_range *range_j =
88efd0a7
PP
288 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
289 range_set, j);
ba38aae7
PP
290
291 if (i == j) {
292 continue;
293 }
294
295 if (range_i->lower.i <= range_j->upper.i &&
296 range_j->lower.i <= range_i->upper.i) {
297 has_overlap = true;
298 goto end;
299 }
300 }
301 }
302
303end:
304 return has_overlap;
305}
306
307static
308bool compare_range_sets(const struct bt_integer_range_set *range_set_a,
309 const struct bt_integer_range_set *range_set_b)
310{
311 uint64_t a_i, b_i;
312 bool is_equal = true;
313
ec4a3354
PP
314 BT_ASSERT_DBG(range_set_a);
315 BT_ASSERT_DBG(range_set_b);
ba38aae7
PP
316
317 if (range_set_a == range_set_b) {
318 goto end;
319 }
320
321 /*
322 * Not super effective for the moment: do a O(N²) compare, also
323 * checking that the sizes match.
324 */
325 if (range_set_a->ranges->len != range_set_b->ranges->len) {
326 is_equal = false;
327 goto end;
328 }
329
330 for (a_i = 0; a_i < range_set_a->ranges->len; a_i++) {
331 const struct bt_integer_range *range_a =
332 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set_a,
333 a_i);
334 bool b_has_range = false;
335
336 for (b_i = 0; b_i < range_set_b->ranges->len; b_i++) {
337 const struct bt_integer_range *range_b =
338 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
339 range_set_b, b_i);
340
341 if (compare_ranges(range_a, range_b)) {
342 b_has_range = true;
343 break;
344 }
345 }
346
347 if (!b_has_range) {
348 is_equal = false;
349 goto end;
350 }
351 }
352
353end:
354 return is_equal;
355}
356
e1c423f9 357bt_bool bt_integer_range_set_unsigned_is_equal(
ba38aae7
PP
358 const struct bt_integer_range_set_unsigned *range_set_a,
359 const struct bt_integer_range_set_unsigned *range_set_b)
360{
361 BT_ASSERT_PRE_DEV_NON_NULL(range_set_a, "Range set A");
362 BT_ASSERT_PRE_DEV_NON_NULL(range_set_b, "Range set B");
363 return (bt_bool) compare_range_sets((const void *) range_set_a,
364 (const void *) range_set_b);
365}
366
e1c423f9 367bt_bool bt_integer_range_set_signed_is_equal(
ba38aae7
PP
368 const struct bt_integer_range_set_signed *range_set_a,
369 const struct bt_integer_range_set_signed *range_set_b)
370{
371 BT_ASSERT_PRE_DEV_NON_NULL(range_set_a, "Range set A");
372 BT_ASSERT_PRE_DEV_NON_NULL(range_set_b, "Range set B");
373 return (bt_bool) compare_range_sets((const void *) range_set_a,
374 (const void *) range_set_b);
375}
376
377void bt_integer_range_set_unsigned_get_ref(
378 const struct bt_integer_range_set_unsigned *range_set)
379{
380 bt_object_get_ref(range_set);
381}
382
383void bt_integer_range_set_unsigned_put_ref(
384 const struct bt_integer_range_set_unsigned *range_set)
385{
386 bt_object_put_ref(range_set);
387}
388
88efd0a7
PP
389void bt_integer_range_set_signed_get_ref(
390 const struct bt_integer_range_set_signed *range_set)
ba38aae7
PP
391{
392 bt_object_get_ref(range_set);
393}
394
88efd0a7
PP
395void bt_integer_range_set_signed_put_ref(
396 const struct bt_integer_range_set_signed *range_set)
ba38aae7
PP
397{
398 bt_object_put_ref(range_set);
399}
This page took 0.045549 seconds and 4 git commands to generate.