I WROTE THE GODDAMN RED BLACK TREE SET (tested only for T=S64 though). IT EVEN TOOK ME LESS THAN 2 WEEKS.
This commit is contained in:
parent
ccba6112fa
commit
4e5a7a8920
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,5 +12,5 @@ vgcore.*
|
||||
*_NORMAL.png
|
||||
*_TEMPLATE.png
|
||||
/out
|
||||
GRAPH*.dot
|
||||
GRAPH*.gv
|
||||
GRAPH*.png
|
||||
@ -22,6 +22,7 @@ int_minmax_function_Definition(U8)
|
||||
int_minmax_function_Definition(U32)
|
||||
int_minmax_function_Definition(S32)
|
||||
int_minmax_function_Definition(U64)
|
||||
int_minmax_function_Definition(S64)
|
||||
int_minmax_function_Definition(float)
|
||||
int_minmax_function_Definition(double)
|
||||
|
||||
|
||||
@ -178,29 +178,35 @@ void codegen_append_rb_tree_set_erase_kind_method(
|
||||
SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[z].right);\n"
|
||||
SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].right;\n"
|
||||
SPACE "assert(x != y && x != z);\n"
|
||||
SPACE "U64 py = self->tree.buf[y].parent;\n" // May be null
|
||||
SPACE "self->tree.buf[x].parent = self->tree.buf[y].parent;\n"
|
||||
SPACE "if (py == 0)\n"
|
||||
SPACE "U64 x_adopter = self->tree.buf[y].parent;\n"
|
||||
SPACE "self->tree.buf[x].parent = x_adopter;\n"
|
||||
SPACE "if (x_adopter == 0)\n"
|
||||
SPACE SPACE "self->root = x;\n"
|
||||
SPACE "else if (self->tree.buf[py].left == y)\n"
|
||||
SPACE SPACE "self->tree.buf[py].left = x;\n"
|
||||
SPACE "else if (self->tree.buf[x_adopter].left == y)\n"
|
||||
SPACE SPACE "self->tree.buf[x_adopter].left = x;\n"
|
||||
SPACE "else\n"
|
||||
SPACE SPACE "self->tree.buf[py].right = x;\n"
|
||||
SPACE SPACE "self->tree.buf[x_adopter].right = x;\n"
|
||||
SPACE "RBTreeColor y_org_clr = self->tree.buf[y].color;\n"
|
||||
SPACE "if (z != y)\n"
|
||||
SPACE "if (z != y) {\n"
|
||||
SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\n"
|
||||
SPACE "U64 L = self->el.len;\n" /* self->tree.len - 1 */
|
||||
SPACE "if (L != z){\n"
|
||||
SPACE SPACE "if (x_adopter == z)\n"
|
||||
SPACE SPACE SPACE "x_adopter = y;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "U64 L = self->el.len;\n"
|
||||
SPACE "if (L != z) {\n"
|
||||
SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, L, z);\n"
|
||||
SPACE SPACE "self->el.buf[z-1] = self->el.buf[L-1];\n"
|
||||
SPACE SPACE "if (L == x)\n"
|
||||
SPACE SPACE SPACE "x = z;\n"
|
||||
SPACE SPACE "else if (L == x_adopter) \n"
|
||||
SPACE SPACE SPACE "x_adopter = z;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "self->tree.buf[x].parent = x_adopter;\n"
|
||||
SPACE "self->tree.len--;\n"
|
||||
SPACE "self->el.len--;\n"
|
||||
SPACE "if (y_org_clr == RBTree_black)\n"
|
||||
SPACE SPACE "RBTree_fix_after_delete(self->tree.buf, &self->root, x);\n"
|
||||
"%v" /* ret_found_case */
|
||||
"%v" /* ret_found_case */
|
||||
"}\n\n",
|
||||
RT, set, method_name, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
not_found_case,
|
||||
|
||||
@ -162,7 +162,7 @@ void RBTree_fix_after_delete(RBTreeNode* tree, U64* root, U64 me){
|
||||
continue;
|
||||
}
|
||||
/* Cases 3,4 */
|
||||
if (tree[nephew_benjamin].right) {
|
||||
if (tree[nephew_benjamin].color == RBTree_black) {
|
||||
/* Case 3 */
|
||||
tree[nephew_firstborn].color = RBTree_black;
|
||||
tree[sister].color = RBTree_red;
|
||||
@ -175,7 +175,8 @@ void RBTree_fix_after_delete(RBTreeNode* tree, U64* root, U64 me){
|
||||
/* Case 4 */
|
||||
tree[sister].color = tree[mom].color;
|
||||
tree[mom].color = RBTree_black;
|
||||
tree[nephew_benjamin].color = RBTree_red;
|
||||
tree[nephew_benjamin].color = RBTree_black;
|
||||
RBTree_left_rotate(tree, root, mom);
|
||||
me = *root;
|
||||
} else if (me == tree[mom].right) { /* We are on the right */
|
||||
U64 sister = tree[mom].left;
|
||||
@ -197,7 +198,7 @@ void RBTree_fix_after_delete(RBTreeNode* tree, U64* root, U64 me){
|
||||
continue;
|
||||
}
|
||||
/* Cases 3,4 */
|
||||
if (tree[nephew_firstborn].left) {
|
||||
if (tree[nephew_firstborn].color == RBTree_black) {
|
||||
/* Case 3 */
|
||||
tree[nephew_benjamin].color = RBTree_black;
|
||||
tree[sister].color = RBTree_red;
|
||||
@ -210,7 +211,8 @@ void RBTree_fix_after_delete(RBTreeNode* tree, U64* root, U64 me){
|
||||
/* Case 4 */
|
||||
tree[sister].color = tree[mom].color;
|
||||
tree[mom].color = RBTree_black;
|
||||
tree[nephew_firstborn].color = RBTree_red;
|
||||
tree[nephew_firstborn].color = RBTree_black;
|
||||
RBTree_right_rotate(tree, root, mom);
|
||||
me = *root;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
#include "../../../../gen/l1_5/BuffRBTree_SetS64.h"
|
||||
#include "../../../../gen/l1/VecAndSpan_int_primitives.h"
|
||||
#include "../../../l1/core/VecU8_as_str.h"
|
||||
#include "../../../l1/system/fileio.h"
|
||||
#include "../../../l1/system/fsmanip.h"
|
||||
#include "../../../l1/system/creating_child_proc.h"
|
||||
|
||||
void check_structure_h_dfs(const VecRBTreeNode* tree, U64 x, VecU8* f){
|
||||
if (x == 0)
|
||||
@ -22,7 +25,31 @@ U32 check_structure_h_dfs_2(RBTreeNode* tree, U64 x){
|
||||
return a + (tree[x].color == RBTree_black ? 1 : 0);
|
||||
}
|
||||
|
||||
void check_structure(const BuffRBTree_SetS64* self){
|
||||
S64 min_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){
|
||||
assert(x != 0 && x < self->tree.len);
|
||||
S64 ans = self->el.buf[x - 1];
|
||||
if (self->tree.buf[x].left != 0) {
|
||||
ans = MIN_S64(ans, min_key_in_subtree(self, self->tree.buf[x].left));
|
||||
}
|
||||
if (self->tree.buf[x].right != 0) {
|
||||
ans = MIN_S64(ans, min_key_in_subtree(self, self->tree.buf[x].right));
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
S64 max_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){
|
||||
assert(x != 0 && x < self->tree.len);
|
||||
S64 ans = self->el.buf[x - 1];
|
||||
if (self->tree.buf[x].left != 0) {
|
||||
ans = MAX_S64(ans, max_key_in_subtree(self, self->tree.buf[x].left));
|
||||
}
|
||||
if (self->tree.buf[x].right != 0) {
|
||||
ans = MAX_S64(ans, max_key_in_subtree(self, self->tree.buf[x].right));
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
void check_only_structure(const BuffRBTree_SetS64* self){
|
||||
check(self->tree.len == self->el.len + 1);
|
||||
check(self->root < self->tree.len);
|
||||
if (self->tree.len > 1) {
|
||||
@ -45,13 +72,15 @@ void check_structure(const BuffRBTree_SetS64* self){
|
||||
check(self->tree.buf[v].right < self->tree.len);
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].parent == v);
|
||||
check(self->el.buf[self->tree.buf[v].left - 1] < self->el.buf[v - 1]);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].right].parent == v);
|
||||
check(self->el.buf[v - 1] < self->el.buf[self->tree.buf[v].right - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check_correctness(const BuffRBTree_SetS64* self){
|
||||
check_only_structure(self);
|
||||
|
||||
/* Checking coloring */
|
||||
check(self->tree.buf[0].color == RBTree_black);
|
||||
@ -64,39 +93,118 @@ void check_structure(const BuffRBTree_SetS64* self){
|
||||
}
|
||||
}
|
||||
check_structure_h_dfs_2(self->tree.buf, self->root);
|
||||
|
||||
/* checking keys, but better */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(self->el.buf[self->tree.buf[v].left - 1] < self->el.buf[v - 1]);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->el.buf[v - 1] < self->el.buf[self->tree.buf[v].right - 1]);
|
||||
}
|
||||
}
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(max_key_in_subtree(self, self->tree.buf[v].left) < self->el.buf[v - 1]);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->el.buf[v - 1] < min_key_in_subtree(self, self->tree.buf[v].right));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void save_tree_to_file(const BuffRBTree_SetS64* set, SpanU8 name){
|
||||
check_structure(set);
|
||||
check_only_structure(set);
|
||||
|
||||
VecS64 ranked_node_to_rb_node = VecS64_new_reserved(set->el.len);
|
||||
{
|
||||
VecS64 bfs_nxt = VecS64_new();
|
||||
VecS64 bfs = VecS64_new();
|
||||
if (set->root != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->root);
|
||||
while (bfs_nxt.len > 0) {
|
||||
VecS64 t = bfs_nxt;
|
||||
bfs_nxt = bfs;
|
||||
bfs = t;
|
||||
for (size_t j = 0; j < bfs.len; j++) {
|
||||
S64 cur = *VecS64_at(&bfs, j);
|
||||
assert(cur != 0);
|
||||
VecS64_append(&ranked_node_to_rb_node, cur);
|
||||
if (cur < 0)
|
||||
continue;
|
||||
if (set->tree.buf[cur].left != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->tree.buf[cur].left);
|
||||
else if (set->tree.buf[cur].right != 0)
|
||||
VecS64_append(&bfs_nxt, -cur);
|
||||
if (set->tree.buf[cur].right != 0)
|
||||
VecS64_append(&bfs_nxt, (S64)set->tree.buf[cur].right);
|
||||
else if (set->tree.buf[cur].left != 0)
|
||||
VecS64_append(&bfs_nxt, -cur);
|
||||
}
|
||||
bfs.len = 0;
|
||||
}
|
||||
}
|
||||
VecU8 graph = VecU8_new();
|
||||
VecU8_append_span(&graph, cstr(
|
||||
"digraph rbtree {\n"
|
||||
" fontsize = 20\n"
|
||||
" rankdir = TB\n"
|
||||
" bgcolor = \"lightgray\"\n"
|
||||
" node [fontname = \"Arial\"];\n"));
|
||||
for (size_t i = 1; i < set->tree.len; i++) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%s"));
|
||||
" node [fontname = \"Arial\", style=\"rounded,filled\", shape=circle];\n"));
|
||||
for (U64 j = 0; j < ranked_node_to_rb_node.len; j++) {
|
||||
S64 cur = ranked_node_to_rb_node.buf[j];
|
||||
assert(cur != 0);
|
||||
if (cur < 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" n_%i [style=invis, label=\"\"]\n", -cur));
|
||||
continue;
|
||||
}
|
||||
U64 i = (U64)cur;
|
||||
VecU8_append_vec(&graph, VecU8_fmt(
|
||||
" v%u [label=%i, xlabel=<<FONT color='%s'>%u</FONT>>, color=%s, fontcolor=%s]\n",
|
||||
i, set->el.buf[i - 1],
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("black") : cstr("red"), i,
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("black") : cstr("red"),
|
||||
set->tree.buf[i].color == RBTree_black ? cstr("white") : cstr("black")));
|
||||
}
|
||||
VecU8_append_span(&graph, cstr("\n"));
|
||||
for (U64 j = 0; j < ranked_node_to_rb_node.len; j++) {
|
||||
S64 cur = ranked_node_to_rb_node.buf[j];
|
||||
if (cur < 0)
|
||||
continue;
|
||||
U64 i = (U64)cur;
|
||||
if (set->tree.buf[i].left != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> v%u [weight=2]\n", i, set->tree.buf[i].left));
|
||||
} else if (set->tree.buf[i].right != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> n_%u [style=invis, weight=3]\n", i, i));
|
||||
}
|
||||
if (set->tree.buf[i].right != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> v%u [weight=2]\n", i, set->tree.buf[i].right));
|
||||
} else if (set->tree.buf[i].left != 0) {
|
||||
VecU8_append_vec(&graph, VecU8_fmt(" v%u -> n_%u [style=invis, weight=3]\n", i, i));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&graph, cstr("}\n"));
|
||||
|
||||
VecU8 dot_filename_nt = VecU8_fmt("GRAPHS/GRAPH_%s.dot%c", name, 0);
|
||||
mkdir_nofail("GRAPHS");
|
||||
VecU8 dot_filename_nt = VecU8_fmt("GRAPHS/GRAPH_%s.gv%c", name, 0);
|
||||
write_whole_file_or_abort((CSTR)dot_filename_nt.buf, VecU8_to_span(&graph));
|
||||
VecU8_drop(graph);
|
||||
VecU8_drop(dot_filename_nt);
|
||||
VecU8 command_nt = VecU8_fmt("dot -Tpng GRAPHS/GRAPH_%s.gv -o GRAPHS/GRAPH_%s.png%c", name, name, 0);
|
||||
calling_system_func_nofail((CSTR)command_nt.buf);
|
||||
VecU8_drop(command_nt);
|
||||
}
|
||||
|
||||
void insert_only(){
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, 42);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 1);
|
||||
check(set.root == 1);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
@ -106,10 +214,10 @@ void insert_only(){
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 42);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 69);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 2);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
@ -118,10 +226,10 @@ void insert_only(){
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 70);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 50);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(set.el.len == 2);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
@ -130,13 +238,13 @@ void insert_only(){
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
ret = BuffRBTree_SetS64_insert(&set, 1);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 2);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
ret = BuffRBTree_SetS64_insert(&set, 3);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
@ -144,7 +252,7 @@ void insert_only(){
|
||||
for (S64 i = 10; i < 100; i++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
@ -153,7 +261,7 @@ void insert_only(){
|
||||
for (S64 i = 99; i >= 10; i--) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
@ -162,10 +270,10 @@ void insert_only(){
|
||||
for (S64 i = 10; i < 100; i++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, i);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
bool ret2 = BuffRBTree_SetS64_insert(&set, 1000 - i);
|
||||
check(ret2);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
}
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
@ -181,7 +289,7 @@ void insert_and_then_find(){
|
||||
for (S64 p = 0; p < 100; p++) {
|
||||
bool ret = BuffRBTree_SetS64_insert(&set, 2 * p);
|
||||
check(ret);
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
for (S64 i = 0; i <= p; i++) {
|
||||
U64 ret1 = BuffRBTree_SetS64_find(&set, 2 * i);
|
||||
check(ret1);
|
||||
@ -196,25 +304,25 @@ void insert_and_delete(){
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
@ -222,11 +330,11 @@ void insert_and_delete(){
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 1));
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_find(&set, 2));
|
||||
|
||||
@ -234,17 +342,180 @@ void insert_and_delete(){
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(BuffRBTree_SetS64_find(&set, 2));
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_structure(&set);
|
||||
check_correctness(&set);
|
||||
check(!BuffRBTree_SetS64_find(&set, 1));
|
||||
check(!BuffRBTree_SetS64_find(&set, 2));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
for (S64 i = -120; i < 1000; i += 10) {
|
||||
check(BuffRBTree_SetS64_insert(&set, i))
|
||||
check_correctness(&set);
|
||||
}
|
||||
// save_tree_to_file(&set, cstr("tree"));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
{
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
check(BuffRBTree_SetS64_insert(&set, 1))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 2))
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_insert(&set, 3))
|
||||
check_correctness(&set);
|
||||
// save_tree_to_file(&set, cstr("trio"));
|
||||
check(BuffRBTree_SetS64_erase(&set, 2));
|
||||
check_correctness(&set);
|
||||
// save_tree_to_file(&set, cstr("duo"));
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MutSpanS64_shuffle(MutSpanS64 span){
|
||||
if (span.len <= 1)
|
||||
return;
|
||||
for (size_t i = span.len-1; i > 0; i--) {
|
||||
size_t j = rand() % (i + 1);
|
||||
S64 temp = span.data[i];
|
||||
span.data[i] = span.data[j];
|
||||
span.data[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
VecS64 gen_cool_sequence(S64 i){
|
||||
VecS64 res = VecS64_new_reserved(i);
|
||||
for (S64 j = 0; j < i; j++) {
|
||||
VecS64_append(&res, (j + 1) * 10);
|
||||
}
|
||||
MutSpanS64_shuffle(VecS64_to_mspan(&res));
|
||||
return res;
|
||||
}
|
||||
|
||||
void chaos(){
|
||||
for (int i = 1; i < 100; i++) {
|
||||
srand(i);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 seq_to_insert = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_insert = seq_to_insert.buf[j];
|
||||
BuffRBTree_SetS64_insert(&set, to_insert);
|
||||
check_correctness(&set);
|
||||
}
|
||||
assert(set.el.len == (size_t)i);
|
||||
// save_tree_to_file(&set, cstr("last_good"));
|
||||
S64 to_delete = (rand() % i + 1) * 10;
|
||||
printf("Started deleting from i=%d\n", i);
|
||||
check(BuffRBTree_SetS64_erase(&set, to_delete));
|
||||
printf("Deleted from i=%d\n", i);
|
||||
check_only_structure(&set);
|
||||
// save_tree_to_file(&set, cstr("fucked_tree"));
|
||||
check_correctness(&set);
|
||||
VecS64_drop(seq_to_insert);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
void triple_black(){
|
||||
BuffRBTree_SetS64 set;
|
||||
{
|
||||
VecRBTreeNode tree = VecRBTreeNode_new_zeroinit(4);
|
||||
tree.buf[1] = (RBTreeNode){.parent = 3};
|
||||
tree.buf[2] = (RBTreeNode){.parent = 3};
|
||||
tree.buf[3] = (RBTreeNode){.left = 2, .right = 1};
|
||||
VecS64 el = VecS64_new_reserved(3);
|
||||
VecS64_append(&el, 300);
|
||||
VecS64_append(&el, 100);
|
||||
VecS64_append(&el, 200);
|
||||
set = (BuffRBTree_SetS64){.tree = tree, .root = 3, .el = el};
|
||||
}
|
||||
check_correctness(&set);
|
||||
check(BuffRBTree_SetS64_erase(&set, 300));
|
||||
check_correctness(&set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
|
||||
void absolute_chaos(){
|
||||
for (int i = 1; i < 100; i++) {
|
||||
srand(i);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 seq_to_insert = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_insert = seq_to_insert.buf[j];
|
||||
check(BuffRBTree_SetS64_insert(&set, to_insert));
|
||||
check_correctness(&set);
|
||||
}
|
||||
printf("Filled chaos with i = %d\n", i);
|
||||
// save_tree_to_file(&set, cstr("i_3"));
|
||||
assert(set.el.len == (size_t)i);
|
||||
VecS64 seq_to_erase = gen_cool_sequence(i);
|
||||
for (int j = 0; j < i; j++) {
|
||||
S64 to_erase = seq_to_erase.buf[j];
|
||||
check(BuffRBTree_SetS64_erase(&set, to_erase));
|
||||
check_correctness(&set);
|
||||
}
|
||||
printf("Emptied chaos with i = %d\n", i);
|
||||
assert(set.el.len == 0);
|
||||
VecS64_drop(seq_to_insert);
|
||||
VecS64_drop(seq_to_erase);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
}
|
||||
}
|
||||
|
||||
void stress(){
|
||||
printf("Prepare for some real stress\n");
|
||||
for (int s = 2; s < 1000; s++) {
|
||||
srand(s);
|
||||
BuffRBTree_SetS64 set = BuffRBTree_SetS64_new();
|
||||
VecS64 real_set = VecS64_new();
|
||||
U32 n = (U32)s;
|
||||
VecS64 complementary_set = VecS64_new_reserved(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
VecS64_append(&complementary_set, (S64)i * 10);
|
||||
}
|
||||
for (int t = 0; t < 1000; t++) {
|
||||
/* Do something */
|
||||
int do_insertion = rand() % 2;
|
||||
if (real_set.len == 0)
|
||||
do_insertion = 1;
|
||||
if (complementary_set.len == 0)
|
||||
do_insertion = 0;
|
||||
if (do_insertion) {
|
||||
assert(complementary_set.len > 0);
|
||||
size_t j = rand() % complementary_set.len;
|
||||
S64 v = VecS64_unordered_pop(&complementary_set, j);
|
||||
VecS64_append(&real_set, v);
|
||||
check(BuffRBTree_SetS64_insert(&set, v));
|
||||
} else {
|
||||
assert(real_set.len > 0);
|
||||
size_t j = rand() % real_set.len;
|
||||
S64 v = VecS64_unordered_pop(&real_set, j);
|
||||
VecS64_append(&complementary_set, v);
|
||||
check(BuffRBTree_SetS64_erase(&set, v));
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
for (size_t j = 0; j < real_set.len; j++) {
|
||||
check(BuffRBTree_SetS64_find(&set, real_set.buf[j]) != 0);
|
||||
}
|
||||
for (size_t j = 0; j < complementary_set.len; j++) {
|
||||
check(BuffRBTree_SetS64_find(&set, complementary_set.buf[j]) == 0);
|
||||
}
|
||||
}
|
||||
VecS64_drop(real_set);
|
||||
BuffRBTree_SetS64_drop(set);
|
||||
printf("Seed s=%d passed test\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
insert_only();
|
||||
insert_and_then_find();
|
||||
insert_and_delete();
|
||||
chaos();
|
||||
triple_black();
|
||||
absolute_chaos();
|
||||
stress();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user