cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / integer-range-set.c
CommitLineData
fb91c0ef 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
fb91c0ef 3 *
0235b0db 4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
fb91c0ef
PP
5 */
6
7#define BT_LOG_TAG "LIB/INT-RANGE-SET"
8#include "lib/logging.h"
9
c4f23e30
FD
10#include <stdbool.h>
11
fb91c0ef 12#include <babeltrace2/babeltrace.h>
c4f23e30 13
d98421f2 14#include "lib/assert-cond.h"
fb91c0ef
PP
15#include "common/assert.h"
16#include "func-status.h"
17#include "integer-range-set.h"
18
1353b066 19BT_EXPORT
6769570a
PP
20uint64_t bt_integer_range_unsigned_get_lower(
21 const struct bt_integer_range_unsigned *u_range)
fb91c0ef
PP
22{
23 const struct bt_integer_range *range = (const void *) u_range;
24
d5b13b9b 25 BT_ASSERT_PRE_DEV_INT_RANGE_NON_NULL(range);
fb91c0ef
PP
26 return range->lower.u;
27}
28
1353b066 29BT_EXPORT
6769570a
PP
30uint64_t bt_integer_range_unsigned_get_upper(
31 const struct bt_integer_range_unsigned *u_range)
fb91c0ef
PP
32{
33 const struct bt_integer_range *range = (const void *) u_range;
34
d5b13b9b 35 BT_ASSERT_PRE_DEV_INT_RANGE_NON_NULL(range);
fb91c0ef
PP
36 return range->upper.u;
37}
38
1353b066 39BT_EXPORT
6769570a
PP
40int64_t bt_integer_range_signed_get_lower(
41 const struct bt_integer_range_signed *i_range)
fb91c0ef
PP
42{
43 const struct bt_integer_range *range = (const void *) i_range;
44
d5b13b9b 45 BT_ASSERT_PRE_DEV_INT_RANGE_NON_NULL(range);
fb91c0ef
PP
46 return range->lower.i;
47}
48
1353b066 49BT_EXPORT
6769570a
PP
50int64_t bt_integer_range_signed_get_upper(
51 const struct bt_integer_range_signed *i_range)
fb91c0ef
PP
52{
53 const struct bt_integer_range *range = (const void *) i_range;
54
d5b13b9b 55 BT_ASSERT_PRE_DEV_INT_RANGE_NON_NULL(range);
fb91c0ef
PP
56 return range->upper.i;
57}
58
59static
60bool compare_ranges(const struct bt_integer_range *range_a,
61 const struct bt_integer_range *range_b)
62{
63 return range_a->lower.u == range_b->lower.u &&
64 range_a->upper.u == range_b->upper.u;
65}
66
1353b066 67BT_EXPORT
cd933d89 68bt_bool bt_integer_range_unsigned_is_equal(
fb91c0ef
PP
69 const struct bt_integer_range_unsigned *range_a,
70 const struct bt_integer_range_unsigned *range_b)
71{
1778c2a4
PP
72 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-a", range_a,
73 "Integer range A");
74 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-b", range_b,
75 "Integer range B");
fb91c0ef
PP
76 return (bt_bool) compare_ranges((const void *) range_a,
77 (const void *) range_b);
78}
79
1353b066 80BT_EXPORT
cd933d89 81bt_bool bt_integer_range_signed_is_equal(
fb91c0ef
PP
82 const struct bt_integer_range_signed *range_a,
83 const struct bt_integer_range_signed *range_b)
84{
1778c2a4
PP
85 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-a", range_a,
86 "Integer range A");
87 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-b", range_b,
88 "Integer range B");
fb91c0ef
PP
89 return (bt_bool) compare_ranges((const void *) range_a,
90 (const void *) range_b);
91}
92
1353b066 93BT_EXPORT
fb91c0ef
PP
94uint64_t bt_integer_range_set_get_range_count(
95 const bt_integer_range_set *range_set)
96{
d5b13b9b 97 BT_ASSERT_PRE_DEV_INT_RANGE_SET_NON_NULL(range_set);
fb91c0ef
PP
98 return (uint64_t) range_set->ranges->len;
99}
100
1353b066 101BT_EXPORT
6769570a
PP
102const struct bt_integer_range_unsigned *
103bt_integer_range_set_unsigned_borrow_range_by_index_const(
104 const bt_integer_range_set_unsigned *u_range_set,
105 uint64_t index)
fb91c0ef 106{
6769570a
PP
107 const struct bt_integer_range_set *range_set =
108 (const void *) u_range_set;
fb91c0ef 109
d5b13b9b 110 BT_ASSERT_PRE_DEV_INT_RANGE_SET_NON_NULL(range_set);
fb91c0ef 111 BT_ASSERT_PRE_DEV_VALID_INDEX(index, range_set->ranges->len);
6769570a
PP
112 return (const void *) BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set,
113 index);
fb91c0ef
PP
114}
115
1353b066 116BT_EXPORT
6769570a
PP
117const struct bt_integer_range_signed *
118bt_integer_range_set_signed_borrow_range_by_index_const(
fb91c0ef
PP
119 const bt_integer_range_set_signed *i_range_set, uint64_t index)
120{
6769570a
PP
121 const struct bt_integer_range_set *range_set =
122 (const void *) i_range_set;
fb91c0ef 123
d5b13b9b 124 BT_ASSERT_PRE_DEV_INT_RANGE_SET_NON_NULL(range_set);
fb91c0ef 125 BT_ASSERT_PRE_DEV_VALID_INDEX(index, range_set->ranges->len);
6769570a
PP
126 return (const void *) BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set,
127 index);
fb91c0ef
PP
128}
129
130static
131void destroy_range_set(struct bt_object *obj)
132{
133 struct bt_integer_range_set *range_set = (void *) obj;
134
6769570a
PP
135 BT_LIB_LOGD("Destroying integer range set: %!+R", range_set);
136
fb91c0ef
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{
6769570a
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);
fb91c0ef
PP
152
153 if (!range_set) {
6769570a
PP
154 BT_LIB_LOGE_APPEND_CAUSE(
155 "Failed to allocate one integer range set.");
fb91c0ef
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(
6769570a 164 "Failed to allocate integer range set's range array.");
fb91c0ef
PP
165 goto error;
166 }
167
6769570a 168 BT_LOGD_STR("Created empty integer range set.");
fb91c0ef
PP
169 goto end;
170
171error:
172 BT_OBJECT_PUT_REF_AND_RESET(range_set);
173
174end:
175 return range_set;
176}
177
1353b066 178BT_EXPORT
fb91c0ef
PP
179struct bt_integer_range_set_unsigned *bt_integer_range_set_unsigned_create(void)
180{
17f3083a
SM
181 BT_ASSERT_PRE_NO_ERROR();
182
fb91c0ef
PP
183 return (void *) create_range_set();
184}
185
1353b066 186BT_EXPORT
fb91c0ef
PP
187struct bt_integer_range_set_signed *bt_integer_range_set_signed_create(void)
188{
17f3083a
SM
189 BT_ASSERT_PRE_NO_ERROR();
190
fb91c0ef
PP
191 return (void *) create_range_set();
192}
193
7c7301d5 194static
fb91c0ef
PP
195void add_range_to_range_set(struct bt_integer_range_set *range_set,
196 uint64_t u_lower, uint64_t u_upper)
197{
198 struct bt_integer_range range = {
199 .lower.u = u_lower,
200 .upper.u = u_upper,
201 };
202
d5b13b9b 203 BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL(range_set);
1778c2a4
PP
204 BT_ASSERT_PRE_DEV_HOT("integer-range-set", range_set,
205 "Integer range set", ": %!+R", range_set);
fb91c0ef 206 g_array_append_val(range_set->ranges, range);
6769570a
PP
207 BT_LIB_LOGD("Added integer range to integer range set: "
208 "%![range-set-]+R, lower-unsigned=%" PRIu64 ", "
209 "upper-unsigned=%" PRIu64, range_set, u_lower, u_upper);
fb91c0ef
PP
210}
211
1353b066 212BT_EXPORT
6769570a
PP
213enum bt_integer_range_set_add_range_status
214bt_integer_range_set_unsigned_add_range(
fb91c0ef
PP
215 struct bt_integer_range_set_unsigned *range_set,
216 uint64_t lower, uint64_t upper)
217{
17f3083a 218 BT_ASSERT_PRE_NO_ERROR();
1778c2a4 219 BT_ASSERT_PRE("lower-lteq-upper", lower <= upper,
fb91c0ef
PP
220 "Range's upper bound is less than lower bound: "
221 "upper=%" PRIu64 ", lower=%" PRIu64, lower, upper);
222 add_range_to_range_set((void *) range_set, lower, upper);
223 return BT_FUNC_STATUS_OK;
224}
225
1353b066 226BT_EXPORT
6769570a
PP
227enum bt_integer_range_set_add_range_status
228bt_integer_range_set_signed_add_range(
fb91c0ef
PP
229 struct bt_integer_range_set_signed *range_set,
230 int64_t lower, int64_t upper)
231{
17f3083a 232 BT_ASSERT_PRE_NO_ERROR();
1778c2a4 233 BT_ASSERT_PRE("lower-lteq-upper", lower <= upper,
fb91c0ef
PP
234 "Range's upper bound is less than lower bound: "
235 "upper=%" PRId64 ", lower=%" PRId64, lower, upper);
236 add_range_to_range_set((void *) range_set,
237 (int64_t) lower, (int64_t) upper);
238 return BT_FUNC_STATUS_OK;
239}
240
fb91c0ef
PP
241void _bt_integer_range_set_freeze(const struct bt_integer_range_set *range_set)
242{
243 BT_ASSERT(range_set);
6769570a 244 BT_LIB_LOGD("Freezing integer range set: %!+R", range_set);
fb91c0ef
PP
245 ((struct bt_integer_range_set *) range_set)->frozen = true;
246}
247
6769570a
PP
248bool bt_integer_range_set_unsigned_has_overlaps(
249 const struct bt_integer_range_set *range_set)
fb91c0ef
PP
250{
251 uint64_t i, j;
252 bool has_overlap = false;
253
254 BT_ASSERT(range_set);
255
256 for (i = 0; i < range_set->ranges->len; i++) {
257 const struct bt_integer_range *range_i =
258 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set, i);
259
260 for (j = 0; j < range_set->ranges->len; j++) {
261 const struct bt_integer_range *range_j =
6769570a
PP
262 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
263 range_set, j);
fb91c0ef
PP
264
265 if (i == j) {
266 continue;
267 }
268
269 if (range_i->lower.u <= range_j->upper.u &&
270 range_j->lower.u <= range_i->upper.u) {
271 has_overlap = true;
272 goto end;
273 }
274 }
275 }
276
277end:
278 return has_overlap;
279}
280
6769570a
PP
281bool bt_integer_range_set_signed_has_overlaps(
282 const struct bt_integer_range_set *range_set)
fb91c0ef
PP
283{
284 uint64_t i, j;
285 bool has_overlap = false;
286
287 BT_ASSERT(range_set);
288
289 for (i = 0; i < range_set->ranges->len; i++) {
290 const struct bt_integer_range *range_i =
291 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set, i);
292
293 for (j = 0; j < range_set->ranges->len; j++) {
294 const struct bt_integer_range *range_j =
6769570a
PP
295 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
296 range_set, j);
fb91c0ef
PP
297
298 if (i == j) {
299 continue;
300 }
301
302 if (range_i->lower.i <= range_j->upper.i &&
303 range_j->lower.i <= range_i->upper.i) {
304 has_overlap = true;
305 goto end;
306 }
307 }
308 }
309
310end:
311 return has_overlap;
312}
313
314static
315bool compare_range_sets(const struct bt_integer_range_set *range_set_a,
316 const struct bt_integer_range_set *range_set_b)
317{
318 uint64_t a_i, b_i;
319 bool is_equal = true;
320
98b15851
PP
321 BT_ASSERT_DBG(range_set_a);
322 BT_ASSERT_DBG(range_set_b);
fb91c0ef
PP
323
324 if (range_set_a == range_set_b) {
325 goto end;
326 }
327
328 /*
329 * Not super effective for the moment: do a O(N²) compare, also
330 * checking that the sizes match.
331 */
332 if (range_set_a->ranges->len != range_set_b->ranges->len) {
333 is_equal = false;
334 goto end;
335 }
336
337 for (a_i = 0; a_i < range_set_a->ranges->len; a_i++) {
338 const struct bt_integer_range *range_a =
339 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(range_set_a,
340 a_i);
341 bool b_has_range = false;
342
343 for (b_i = 0; b_i < range_set_b->ranges->len; b_i++) {
344 const struct bt_integer_range *range_b =
345 BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
346 range_set_b, b_i);
347
348 if (compare_ranges(range_a, range_b)) {
349 b_has_range = true;
350 break;
351 }
352 }
353
354 if (!b_has_range) {
355 is_equal = false;
356 goto end;
357 }
358 }
359
360end:
361 return is_equal;
362}
363
1353b066 364BT_EXPORT
cd933d89 365bt_bool bt_integer_range_set_unsigned_is_equal(
fb91c0ef
PP
366 const struct bt_integer_range_set_unsigned *range_set_a,
367 const struct bt_integer_range_set_unsigned *range_set_b)
368{
1778c2a4
PP
369 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-set-a", range_set_a,
370 "Range set A");
371 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-set-b", range_set_b,
372 "Range set B");
fb91c0ef
PP
373 return (bt_bool) compare_range_sets((const void *) range_set_a,
374 (const void *) range_set_b);
375}
376
1353b066 377BT_EXPORT
cd933d89 378bt_bool bt_integer_range_set_signed_is_equal(
fb91c0ef
PP
379 const struct bt_integer_range_set_signed *range_set_a,
380 const struct bt_integer_range_set_signed *range_set_b)
381{
1778c2a4
PP
382 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-set-a", range_set_a,
383 "Range set A");
384 BT_ASSERT_PRE_DEV_NON_NULL("integer-range-set-b", range_set_b,
385 "Range set B");
fb91c0ef
PP
386 return (bt_bool) compare_range_sets((const void *) range_set_a,
387 (const void *) range_set_b);
388}
389
1353b066 390BT_EXPORT
fb91c0ef
PP
391void bt_integer_range_set_unsigned_get_ref(
392 const struct bt_integer_range_set_unsigned *range_set)
393{
394 bt_object_get_ref(range_set);
395}
396
1353b066 397BT_EXPORT
fb91c0ef
PP
398void bt_integer_range_set_unsigned_put_ref(
399 const struct bt_integer_range_set_unsigned *range_set)
400{
401 bt_object_put_ref(range_set);
402}
403
1353b066 404BT_EXPORT
6769570a
PP
405void bt_integer_range_set_signed_get_ref(
406 const struct bt_integer_range_set_signed *range_set)
fb91c0ef
PP
407{
408 bt_object_get_ref(range_set);
409}
410
1353b066 411BT_EXPORT
6769570a
PP
412void bt_integer_range_set_signed_put_ref(
413 const struct bt_integer_range_set_signed *range_set)
fb91c0ef
PP
414{
415 bt_object_put_ref(range_set);
416}
This page took 0.08506 seconds and 4 git commands to generate.