libcdsb/src/set/modify.c

75 lines
1.9 KiB
C
Raw Normal View History

2022-08-19 17:19:22 +03:00
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/set.h"
#include "../__internal/rbtree.h"
#include "../__internal/assert.h"
2023-03-23 16:21:52 +03:00
bool libcdsb_vset_insert(set_t* x, vtype_variable value) {
2022-08-19 17:19:22 +03:00
int cmp;
rbnode_t* n;
rbnode_t* p;
2022-08-19 20:00:10 +03:00
if (!rbnode_is_empty(n = x->root)) {
2022-08-19 17:19:22 +03:00
do {
p = n;
2023-03-23 18:11:34 +03:00
cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type);
2022-08-19 17:19:22 +03:00
2022-08-19 20:00:10 +03:00
if (cmp == 0) return false;
2022-08-19 17:19:22 +03:00
n = (cmp < 0) ? n->left : n->right;
} while (!rbnode_is_empty(n));
2022-08-19 20:00:10 +03:00
n = rbnode_create(nullptr, p, 1);
2022-08-19 17:19:22 +03:00
if (cmp < 0) p->left = n;
else p->right = n;
if (!rbnode_is_root(p))
rbnode_fixup(&x->root, n);
2022-08-19 20:00:10 +03:00
} else n = x->root = rbnode_create(nullptr, rbnode_empty, 0);
2023-03-23 16:21:52 +03:00
n->value = vnode_tcreate(x->type, value.pointer, value.type);
2022-08-19 17:19:22 +03:00
return true;
}
2023-03-23 16:21:52 +03:00
bool libcdsb_vset_attach(set_t* x, vtype_variable value) {
2022-08-19 17:19:22 +03:00
int cmp;
rbnode_t* n;
rbnode_t* p;
2022-08-19 20:00:10 +03:00
vnode_t vn;
2022-08-19 17:19:22 +03:00
2023-03-23 16:21:52 +03:00
vnode_tattach(&vn, x->type, value.pointer, value.type);
n = x->root;
value.type = x->type;
value.pointer = vnode_peek(&vn, value.type);
2022-08-19 17:19:22 +03:00
if (!rbnode_is_empty(n)) {
do {
p = n;
2023-03-23 18:11:34 +03:00
cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type);
2022-08-19 17:19:22 +03:00
2022-08-19 20:00:10 +03:00
if (cmp == 0) {
2023-03-23 16:21:52 +03:00
vnode_free(&vn, value.type);
2022-08-19 20:00:10 +03:00
return false;
}
2022-08-19 17:19:22 +03:00
n = (cmp < 0) ? n->left : n->right;
} while (!rbnode_is_empty(n));
2022-08-19 20:00:10 +03:00
n = rbnode_create(vn, p, 1);
2022-08-19 17:19:22 +03:00
if (cmp < 0) p->left = n;
else p->right = n;
if (!rbnode_is_root(p))
rbnode_fixup(&x->root, n);
2022-08-19 20:00:10 +03:00
} else n = x->root = rbnode_create(vn, rbnode_empty, 0);
2022-08-19 17:19:22 +03:00
return true;
}