Skip to content

Commit dc1968a

Browse files
Use upstream cavl2 (#253)
File copied from [cavl c-2.1.0](https://github.com/pavel-kirienko/cavl) without changes.
1 parent a421943 commit dc1968a

File tree

1 file changed

+84
-131
lines changed

1 file changed

+84
-131
lines changed

lib/cavl2/cavl2.h

Lines changed: 84 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,19 @@
5151
/// If Cavl is used in throughput-critical code, then it is recommended to disable assertion checks as they may
5252
/// be costly in terms of execution time.
5353
#ifndef CAVL2_ASSERT
54-
# if defined(CAVL2_NO_ASSERT) && CAVL2_NO_ASSERT
55-
# define CAVL2_ASSERT(x) (void) 0
56-
# else
57-
# include <assert.h>
58-
# define CAVL2_ASSERT(x) assert(x)
59-
# endif
54+
#if defined(CAVL2_NO_ASSERT) && CAVL2_NO_ASSERT
55+
#define CAVL2_ASSERT(x) (void)0
56+
#else
57+
#include <assert.h>
58+
#define CAVL2_ASSERT(x) assert(x)
59+
#endif
6060
#endif
6161

6262
#ifdef __cplusplus
6363
// This is, strictly speaking, useless because we do not define any functions with external linkage here,
6464
// but it tells static analyzers that what follows should be interpreted as C code rather than C++.
65-
extern "C" {
65+
extern "C"
66+
{
6667
#endif
6768

6869
// ---------------------------------------- PUBLIC API SECTION ----------------------------------------
@@ -81,11 +82,11 @@ extern "C" {
8182
/// };
8283
struct cavl2_t
8384
{
84-
struct cavl2_t* up; ///< Parent node, NULL in the root.
85-
struct cavl2_t* lr[2]; ///< Left child (lesser), right child (greater).
86-
int_fast8_t bf; ///< Balance factor is positive when right-heavy. Allowed values are {-1, 0, +1}.
85+
struct cavl2_t* up; ///< Parent node, NULL in the root.
86+
struct cavl2_t* lr[2]; ///< Left child (lesser), right child (greater).
87+
int_fast8_t bf; ///< Balance factor is positive when right-heavy. Allowed values are {-1, 0, +1}.
8788
};
88-
# define CAVL2_T struct cavl2_t
89+
#define CAVL2_T struct cavl2_t
8990
#endif
9091

9192
#if defined(static_assert) || defined(__cplusplus)
@@ -96,7 +97,7 @@ static_assert(sizeof(CAVL2_T) <= sizeof(void* [4]), "Bad size");
9697
/// The type shall be a signed integer type.
9798
/// Only three possible states of the result are considered: negative, zero, and positive; the magnitude is ignored.
9899
#ifndef CAVL2_RELATION
99-
# define CAVL2_RELATION ptrdiff_t
100+
#define CAVL2_RELATION ptrdiff_t
100101
#endif
101102
/// Returns POSITIVE if the search target is GREATER than the provided node, negative if smaller, zero on match (found).
102103
typedef CAVL2_RELATION (*cavl2_comparator_t)(const void* user, const CAVL2_T* node);
@@ -143,8 +144,7 @@ static inline CAVL2_T* cavl2_extremum(CAVL2_T* const root, const bool maximum)
143144
{
144145
CAVL2_T* result = NULL;
145146
CAVL2_T* c = root;
146-
while (c != NULL)
147-
{
147+
while (c != NULL) {
148148
result = c;
149149
c = c->lr[maximum];
150150
}
@@ -167,18 +167,13 @@ static inline CAVL2_T* cavl2_max(CAVL2_T* const root) { return cavl2_extremum(ro
167167
static inline CAVL2_T* cavl2_next_greater(CAVL2_T* const node)
168168
{
169169
CAVL2_T* c = NULL;
170-
if (node != NULL)
171-
{
172-
if (node->lr[1] != NULL)
173-
{
170+
if (node != NULL) {
171+
if (node->lr[1] != NULL) {
174172
c = cavl2_min(node->lr[1]);
175-
}
176-
else
177-
{
173+
} else {
178174
const CAVL2_T* n = node;
179175
CAVL2_T* p = node->up;
180-
while ((p != NULL) && (p->lr[1] == n))
181-
{
176+
while ((p != NULL) && (p->lr[1] == n)) {
182177
n = p;
183178
p = p->up;
184179
}
@@ -192,7 +187,7 @@ static inline CAVL2_T* cavl2_next_greater(CAVL2_T* const node)
192187
/// It is meant for use with cavl2_find_or_insert().
193188
static inline CAVL2_T* cavl2_trivial_factory(void* const user)
194189
{
195-
return (CAVL2_T*) user;
190+
return (CAVL2_T*)user;
196191
}
197192

198193
/// A convenience macro for use when a struct is a member of multiple AVL trees. For example:
@@ -213,11 +208,11 @@ static inline CAVL2_T* cavl2_trivial_factory(void* const user)
213208
/// if (tree_node_b == NULL) { ... } // do something else
214209
/// struct my_type_t* my_struct = CAVL2_TO_OWNER(tree_node_b, struct my_type_t, tree_b);
215210
///
216-
/// The result is undefined if the tree_node_ptr is not a valid pointer to the tree node. Check for NULL first.
217-
#define CAVL2_TO_OWNER(tree_node_ptr, owner_type, owner_tree_node_field) \
218-
(((tree_node_ptr) == NULL) \
219-
? NULL \
220-
: (owner_type*) (void*) (((char*) (tree_node_ptr)) - offsetof(owner_type, owner_tree_node_field))) // NOLINT
211+
/// The result is undefined if the tree_node_ptr is not a valid pointer to the tree node.
212+
#define CAVL2_TO_OWNER(tree_node_ptr, owner_type, owner_tree_node_field) \
213+
(((tree_node_ptr) == NULL) \
214+
? NULL \
215+
: ((owner_type*)(void*)(((char*)(tree_node_ptr)) - offsetof(owner_type, owner_tree_node_field)))) // NOLINT
221216

222217
// ---------------------------------------- END OF PUBLIC API SECTION ----------------------------------------
223218
// ---------------------------------------- POLICE LINE DO NOT CROSS ----------------------------------------
@@ -227,15 +222,13 @@ static inline void _cavl2_rotate(CAVL2_T* const x, const bool r)
227222
{
228223
CAVL2_ASSERT((x != NULL) && (x->lr[!r] != NULL) && ((x->bf >= -1) && (x->bf <= +1)));
229224
CAVL2_T* const z = x->lr[!r];
230-
if (x->up != NULL)
231-
{
225+
if (x->up != NULL) {
232226
x->up->lr[x->up->lr[1] == x] = z;
233227
}
234228
z->up = x->up;
235229
x->up = z;
236230
x->lr[!r] = z->lr[r];
237-
if (x->lr[!r] != NULL)
238-
{
231+
if (x->lr[!r] != NULL) {
239232
x->lr[!r]->up = x;
240233
}
241234
z->lr[r] = x;
@@ -248,57 +241,43 @@ static inline CAVL2_T* _cavl2_adjust_balance(CAVL2_T* const x, const bool increm
248241
{
249242
CAVL2_ASSERT((x != NULL) && ((x->bf >= -1) && (x->bf <= +1)));
250243
CAVL2_T* out = x;
251-
const int_fast8_t new_bf = (int_fast8_t) (x->bf + (increment ? +1 : -1));
252-
if ((new_bf < -1) || (new_bf > 1))
253-
{
254-
const bool r = new_bf < 0; // bf<0 if left-heavy --> right rotation is needed.
255-
const int_fast8_t sign = r ? +1 : -1; // Positive if we are rotating right.
244+
const int_fast8_t new_bf = (int_fast8_t)(x->bf + (increment ? +1 : -1));
245+
if ((new_bf < -1) || (new_bf > 1)) {
246+
const bool r = new_bf < 0; // bf<0 if left-heavy --> right rotation is needed.
247+
const int_fast8_t sign = r ? +1 : -1; // Positive if we are rotating right.
256248
CAVL2_T* const z = x->lr[!r];
257-
CAVL2_ASSERT(z != NULL); // Heavy side cannot be empty. NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
258-
if ((z->bf * sign) <= 0)
259-
{ // Parent and child are heavy on the same side or the child is balanced.
249+
CAVL2_ASSERT(z != NULL); // Heavy side cannot be empty. NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
250+
if ((z->bf * sign) <= 0) { // Parent and child are heavy on the same side or the child is balanced.
260251
out = z;
261252
_cavl2_rotate(x, r);
262-
if (0 == z->bf)
263-
{
264-
x->bf = (int_fast8_t) (-sign);
265-
z->bf = (int_fast8_t) (+sign);
266-
}
267-
else
268-
{
253+
if (0 == z->bf) {
254+
x->bf = (int_fast8_t)(-sign);
255+
z->bf = (int_fast8_t)(+sign);
256+
} else {
269257
x->bf = 0;
270258
z->bf = 0;
271259
}
272-
}
273-
else
274-
{ // Otherwise, the child needs to be rotated in the opposite direction first.
260+
} else { // Otherwise, the child needs to be rotated in the opposite direction first.
275261
CAVL2_T* const y = z->lr[r];
276-
CAVL2_ASSERT(y != NULL); // Heavy side cannot be empty.
262+
CAVL2_ASSERT(y != NULL); // Heavy side cannot be empty.
277263
out = y;
278264
_cavl2_rotate(z, !r);
279265
_cavl2_rotate(x, r);
280-
if ((y->bf * sign) < 0)
281-
{
282-
x->bf = (int_fast8_t) (+sign);
266+
if ((y->bf * sign) < 0) {
267+
x->bf = (int_fast8_t)(+sign);
283268
y->bf = 0;
284269
z->bf = 0;
285-
}
286-
else if ((y->bf * sign) > 0)
287-
{
270+
} else if ((y->bf * sign) > 0) {
288271
x->bf = 0;
289272
y->bf = 0;
290-
z->bf = (int_fast8_t) (-sign);
291-
}
292-
else
293-
{
273+
z->bf = (int_fast8_t)(-sign);
274+
} else {
294275
x->bf = 0;
295276
z->bf = 0;
296277
}
297278
}
298-
}
299-
else
300-
{
301-
x->bf = new_bf; // Balancing not needed, just update the balance factor and call it a day.
279+
} else {
280+
x->bf = new_bf; // Balancing not needed, just update the balance factor and call it a day.
302281
}
303282
return out;
304283
}
@@ -309,21 +288,20 @@ static inline CAVL2_T* _cavl2_adjust_balance(CAVL2_T* const x, const bool increm
309288
static inline CAVL2_T* _cavl2_retrace_on_growth(CAVL2_T* const added)
310289
{
311290
CAVL2_ASSERT((added != NULL) && (0 == added->bf));
312-
CAVL2_T* c = added; // Child
313-
CAVL2_T* p = added->up; // Parent
314-
while (p != NULL)
315-
{
316-
const bool r = p->lr[1] == c; // c is the right child of parent
291+
CAVL2_T* c = added; // Child
292+
CAVL2_T* p = added->up; // Parent
293+
while (p != NULL) {
294+
const bool r = p->lr[1] == c; // c is the right child of parent
317295
CAVL2_ASSERT(p->lr[r] == c);
318296
c = _cavl2_adjust_balance(p, r);
319297
p = c->up;
320-
if (0 == c->bf)
321-
{ // The height change of the subtree made this parent perfectly balanced (as all things should be),
322-
break; // hence, the height of the outer subtree is unchanged, so upper balance factors are unchanged.
298+
if (0 ==
299+
c->bf) { // The height change of the subtree made this parent perfectly balanced (as all things should be),
300+
break; // hence, the height of the outer subtree is unchanged, so upper balance factors are unchanged.
323301
}
324302
}
325303
CAVL2_ASSERT(c != NULL);
326-
return (NULL == p) ? c : NULL; // New root or nothing.
304+
return (NULL == p) ? c : NULL; // New root or nothing.
327305
}
328306

329307
static inline CAVL2_T* cavl2_find_or_insert(CAVL2_T** const root,
@@ -333,35 +311,29 @@ static inline CAVL2_T* cavl2_find_or_insert(CAVL2_T** const root,
333311
const cavl2_factory_t factory)
334312
{
335313
CAVL2_T* out = NULL;
336-
if ((root != NULL) && (comparator != NULL))
337-
{
314+
if ((root != NULL) && (comparator != NULL)) {
338315
CAVL2_T* up = *root;
339316
CAVL2_T** n = root;
340-
while (*n != NULL)
341-
{
317+
while (*n != NULL) {
342318
const CAVL2_RELATION cmp = comparator(user_comparator, *n);
343-
if (0 == cmp)
344-
{
319+
if (0 == cmp) {
345320
out = *n;
346321
break;
347322
}
348323
up = *n;
349324
n = &(*n)->lr[cmp > 0];
350325
CAVL2_ASSERT((NULL == *n) || ((*n)->up == up));
351326
}
352-
if (NULL == out)
353-
{
327+
if (NULL == out) {
354328
out = (NULL == factory) ? NULL : factory(user_factory);
355-
if (out != NULL)
356-
{
357-
*n = out; // Overwrite the pointer to the new node in the parent node.
329+
if (out != NULL) {
330+
*n = out; // Overwrite the pointer to the new node in the parent node.
358331
out->lr[0] = NULL;
359332
out->lr[1] = NULL;
360333
out->up = up;
361334
out->bf = 0;
362335
CAVL2_T* const rt = _cavl2_retrace_on_growth(out);
363-
if (rt != NULL)
364-
{
336+
if (rt != NULL) {
365337
*root = rt;
366338
}
367339
}
@@ -372,90 +344,71 @@ static inline CAVL2_T* cavl2_find_or_insert(CAVL2_T** const root,
372344

373345
static inline void cavl2_remove(CAVL2_T** const root, const CAVL2_T* const node)
374346
{
375-
if ((root != NULL) && (node != NULL))
376-
{
377-
CAVL2_ASSERT(*root != NULL); // Otherwise, the node would have to be NULL.
347+
if ((root != NULL) && (node != NULL)) {
348+
CAVL2_ASSERT(*root != NULL); // Otherwise, the node would have to be NULL.
378349
CAVL2_ASSERT((node->up != NULL) || (node == *root));
379-
CAVL2_T* p = NULL; // The lowest parent node that suffered a shortening of its subtree.
380-
bool r = false; // Which side of the above was shortened.
350+
CAVL2_T* p = NULL; // The lowest parent node that suffered a shortening of its subtree.
351+
bool r = false; // Which side of the above was shortened.
381352
// The first step is to update the topology and remember the node where to start the retracing from later.
382353
// Balancing is not performed yet so we may end up with an unbalanced tree.
383-
if ((node->lr[0] != NULL) && (node->lr[1] != NULL))
384-
{
354+
if ((node->lr[0] != NULL) && (node->lr[1] != NULL)) {
385355
CAVL2_T* const re = cavl2_extremum(node->lr[1], false);
386356
CAVL2_ASSERT((re != NULL) && (NULL == re->lr[0]) && (re->up != NULL));
387357
re->bf = node->bf;
388358
re->lr[0] = node->lr[0];
389359
re->lr[0]->up = re;
390-
if (re->up != node)
391-
{
392-
p = re->up; // Retracing starts with the ex-parent of our replacement node.
360+
if (re->up != node) {
361+
p = re->up; // Retracing starts with the ex-parent of our replacement node.
393362
CAVL2_ASSERT(p->lr[0] == re);
394-
p->lr[0] = re->lr[1]; // Reducing the height of the left subtree here.
395-
if (p->lr[0] != NULL)
396-
{
363+
p->lr[0] = re->lr[1]; // Reducing the height of the left subtree here.
364+
if (p->lr[0] != NULL) {
397365
p->lr[0]->up = p;
398366
}
399367
re->lr[1] = node->lr[1];
400368
re->lr[1]->up = re;
401369
r = false;
402-
}
403-
else // In this case, we are reducing the height of the right subtree, so r=1.
370+
} else // In this case, we are reducing the height of the right subtree, so r=1.
404371
{
405-
p = re; // Retracing starts with the replacement node itself as we are deleting its parent.
406-
r = true; // The right child of the replacement node remains the same so we don't bother relinking it.
372+
p = re; // Retracing starts with the replacement node itself as we are deleting its parent.
373+
r = true; // The right child of the replacement node remains the same so we don't bother relinking it.
407374
}
408375
re->up = node->up;
409-
if (re->up != NULL)
410-
{
411-
re->up->lr[re->up->lr[1] == node] = re; // Replace link in the parent of node.
412-
}
413-
else
414-
{
376+
if (re->up != NULL) {
377+
re->up->lr[re->up->lr[1] == node] = re; // Replace link in the parent of node.
378+
} else {
415379
*root = re;
416380
}
417-
}
418-
else
419-
{ // Either or both of the children are NULL.
381+
} else { // Either or both of the children are NULL.
420382
p = node->up;
421383
const bool rr = node->lr[1] != NULL;
422-
if (node->lr[rr] != NULL)
423-
{
384+
if (node->lr[rr] != NULL) {
424385
node->lr[rr]->up = p;
425386
}
426-
if (p != NULL)
427-
{
387+
if (p != NULL) {
428388
r = p->lr[1] == node;
429389
p->lr[r] = node->lr[rr];
430-
if (p->lr[r] != NULL)
431-
{
390+
if (p->lr[r] != NULL) {
432391
p->lr[r]->up = p;
433392
}
434-
}
435-
else
436-
{
393+
} else {
437394
*root = node->lr[rr];
438395
}
439396
}
440397
// Now that the topology is updated, perform the retracing to restore balance. We climb up adjusting the
441398
// balance factors until we reach the root or a parent whose balance factor becomes plus/minus one, which
442399
// means that that parent was able to absorb the balance delta; in other words, the height of the outer
443400
// subtree is unchanged, so upper balance factors shall be kept unchanged.
444-
if (p != NULL)
445-
{
401+
if (p != NULL) {
446402
CAVL2_T* c = NULL;
447-
for (;;)
448-
{
403+
for (;;) {
449404
c = _cavl2_adjust_balance(p, !r);
450405
p = c->up;
451-
if ((c->bf != 0) || (NULL == p))
452-
{ // Reached the root or the height difference is absorbed by c.
406+
if ((c->bf != 0) || (NULL == p)) { // Reached the root or the height difference is absorbed by c.
453407
break;
454408
}
455409
r = p->lr[1] == c;
456410
}
457-
if (NULL == p)
458-
{
411+
if (NULL == p) {
459412
CAVL2_ASSERT(c != NULL);
460413
*root = c;
461414
}

0 commit comments

Comments
 (0)