Fixed hella lot of bugs in rb tree. Wrote tests for BuffRBTreeBy***_SetU64Segment (they work)
This commit is contained in:
parent
ba7e37e84e
commit
497808ddeb
@ -53,6 +53,7 @@ target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -l
|
||||
#add_executable(3_render_test src/l2/tests/r3/r3.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
#target_link_libraries(3_render_test -lwayland-client -lm -lvulkan -lxkbcommon)
|
||||
|
||||
add_executable(l2t0_2 src/l2/tests/data_structures/t0_2.c)
|
||||
add_executable(l2t2 src/l2/tests/data_structures/t2.c)
|
||||
|
||||
#add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
|
||||
@ -50,6 +50,15 @@ void generate_util_temp_very_base_headers() {
|
||||
}
|
||||
generate_guarded_span_company_for_primitive(cstr("l1"), cstr(""),
|
||||
cstr("CSTR"), cstr(""), true, false);
|
||||
|
||||
generate_util_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
(util_templates_instantiation_options){.T = cstr("U64Segment"), .t_primitive = true, .vec_extended = true});
|
||||
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
(option_template_instantiation_op){.T = cstr("U64Segment"), .t_primitive = true});
|
||||
/* Required by BuffRBTree_Set */
|
||||
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
(option_template_instantiation_op){.T = cstr("RefU64Segment"), .t_primitive = true});
|
||||
|
||||
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),
|
||||
cstr(""), cstr("VecU8"), cstr("#include \"VecAndSpan_U8.h\""), true, false);
|
||||
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),
|
||||
|
||||
@ -48,4 +48,7 @@ bool U64Segment_less_by_len_and_start_resp_align(const U64Segment* A, const U64S
|
||||
return len_A < len_B;
|
||||
}
|
||||
|
||||
/* Required by BuffRBTree_Set. That was a really tough decision */
|
||||
typedef const U64Segment* RefU64Segment;
|
||||
|
||||
#endif
|
||||
|
||||
@ -10,7 +10,10 @@ void generate_l1_5_template_instantiation_for_base_types(){
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../l1/VecAndSpan_S64.h\""),
|
||||
(set_instantiation_op){.T = cstr("S64"), .t_integer = true});
|
||||
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
SpanU8 u64seg_dep = cstr("#include \"../l1/VecU64Segment.h\"\n"
|
||||
"#include \"../l1/OptionU64Segment.h\"\n"
|
||||
"#include \"../l1/OptionRefU64Segment.h\"");
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
|
||||
(set_instantiation_op){
|
||||
.T = cstr("U64Segment"),
|
||||
.t_primitive = true,
|
||||
@ -18,12 +21,22 @@ void generate_l1_5_template_instantiation_for_base_types(){
|
||||
.alternative_less = cstr("U64Segment_less_by_start"),
|
||||
.alternative_comp_set_name_embed = cstr("Start")
|
||||
});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
|
||||
(set_instantiation_op){
|
||||
.T = cstr("U64Segment"),
|
||||
.t_primitive = true,
|
||||
.alternative_less = cstr("U64Segment_less_by_len_and_start"),
|
||||
.alternative_comp_set_name_embed = cstr("LenAndStart")
|
||||
.alternative_comp_set_name_embed = cstr("Len")
|
||||
});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, u64seg_dep,
|
||||
(set_instantiation_op){
|
||||
.T = cstr("U64Segment"),
|
||||
.t_primitive = true,
|
||||
/* comparison takes additional U8 parameter */
|
||||
.alternative_less = cstr("U64Segment_less_by_len_and_start_resp_align"),
|
||||
.alternative_equal = cstr("U64Segment_equal_U64Segment_resp_align"),
|
||||
.alternative_comp_set_name_embed = cstr("LenRespAlign"),
|
||||
.guest_data_T = cstr("U8")
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op o
|
||||
}
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key == self->el.buf[cur - 1]");
|
||||
return VecU8_fmt("%s_equal_%s(ref, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
return VecU8_fmt("%s_equal_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
/* When key is given by a pointer into some method of Buff_RBTreeSet */
|
||||
@ -106,15 +106,15 @@ NODISCARD VecU8 codegen_rb_tree_set_option_returned_ref_t(set_instantiation_op o
|
||||
* we return it from self->el array */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_some_ref_t(set_instantiation_op op, SpanU8 index_var_name){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("Some_%s(self->el[%s - 1])", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_Ref%s(&self->el[%s - 1])", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_%s(self->el.buf[%s - 1])", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_Ref%s(&self->el.buf[%s - 1])", op.T, index_var_name);
|
||||
}
|
||||
|
||||
/* Suppose some method returns pointer to key (ofc wrapped in option). But this time we found nothing */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_ref_t(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("Some_%s()", op.T);
|
||||
return VecU8_fmt("Some_Ref%s()", op.T);
|
||||
return VecU8_fmt("None_%s()", op.T);
|
||||
return VecU8_fmt("None_Ref%s()", op.T);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_rb_tree_set_option_returned_value_t(set_instantiation_op op){
|
||||
@ -272,7 +272,7 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new(%s guest) {\n" /* set, set, op.guest_data_T */
|
||||
SPACE "return (%s){.tree = VecRBTreeNode_new_zeroinit(1), .root = 0, .el = Vec%s_new(), .guest = guest};\n" /* set, op.T */
|
||||
"}\n\n", set, set, set, op.T));
|
||||
"}\n\n", set, set, op.guest_data_T, set, op.T));
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_reserved(%s guest, size_t size) {\n" /* set, set, op.guest_data_T */
|
||||
SPACE "return (%s){.tree = (VecRBTreeNode){\n"
|
||||
@ -302,7 +302,7 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
* it returns true if insertion was done, false if collision happened and key was not inserted */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("insert"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
op.t_primitive ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(key);\n" /* op.T */
|
||||
@ -314,13 +314,13 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
* previous element with equal key it it was found. It still returns true if no conflict has happened, though */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("erase_substitute"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
op.t_primitive ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(self->el.buf[cur - 1]);\n"
|
||||
"self->el.buf[cur - 1] = key;\n"
|
||||
"return false;\n"
|
||||
));
|
||||
"return false;\n",
|
||||
op.T));
|
||||
|
||||
/* Method _pop_substitute() is just like _erase_substitute(), but it returns a previous key
|
||||
* that was overthrown after collision. Wrapped in option, ofcourse */
|
||||
@ -383,7 +383,7 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
codegen_append_rb_tree_set_erase_kind_method(&res, op, set, cstr("pop"),
|
||||
codegen_rb_tree_set_option_returned_value_t(op),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_none_t(op)),
|
||||
VecU8_fmt("%s saved = self->el[cur - 1];\n", op.T),
|
||||
VecU8_fmt("%s saved = self->el.buf[cur - 1];\n", op.T),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_some_t(op, cstr("saved")))
|
||||
);
|
||||
}
|
||||
|
||||
@ -487,12 +487,14 @@ void stress(){
|
||||
S64 v = VecS64_unordered_pop(&complementary_set, j);
|
||||
VecS64_append(&real_set, v);
|
||||
check(BuffRBTree_SetS64_insert(&set, v));
|
||||
check_correctness(&set);
|
||||
} 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));
|
||||
check_correctness(&set);
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
|
||||
@ -0,0 +1,378 @@
|
||||
#include "../../../../gen/l1_5/BuffRBTreeByLen_SetU64Segment.h"
|
||||
#include "../../../../gen/l1_5/BuffRBTreeByStart_SetU64Segment.h"
|
||||
#include "../../../../gen/l1_5/BuffRBTreeByLenRespAlign_SetU64Segment.h"
|
||||
#include "../../../l1/core/VecU8_as_str.h"
|
||||
|
||||
U32 check_structure_h_dfs(const RBTreeNode* tree, U64 x, VecU8* f){
|
||||
if (x == 0)
|
||||
return 0;
|
||||
if (*VecU8_at(f, x - 1) != 0)
|
||||
check(false);
|
||||
*VecU8_mat(f, x - 1) = 1;
|
||||
U32 a = check_structure_h_dfs(tree, tree[x].left, f);
|
||||
U32 b = check_structure_h_dfs(tree, tree[x].right, f);
|
||||
check(a == b);
|
||||
return a + (tree[x].color == RBTree_black ? 1 : 0);
|
||||
}
|
||||
|
||||
void check_correctness_ByStart(const BuffRBTreeByStart_SetU64Segment* self){
|
||||
check(self->tree.len == self->el.len + 1);
|
||||
check(self->root < self->tree.len);
|
||||
if (self->tree.len > 1) {
|
||||
check(self->root != 0);
|
||||
}
|
||||
VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
|
||||
check_structure_h_dfs(self->tree.buf, self->root, &f);
|
||||
for (size_t i = 0; i < self->tree.len - 1; i++) {
|
||||
check(*VecU8_at(&f, i));
|
||||
}
|
||||
VecU8_drop(f); /* f invalidated */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (v == self->root) {
|
||||
check(self->tree.buf[v].parent == 0);
|
||||
} else {
|
||||
check(self->tree.buf[v].parent != 0);
|
||||
}
|
||||
check(self->tree.buf[v].parent < self->tree.len);
|
||||
check(self->tree.buf[v].left < self->tree.len);
|
||||
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);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].right].parent == v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Checking coloring */
|
||||
check(self->tree.buf[0].color == RBTree_black);
|
||||
if (self->root != 0)
|
||||
check(self->tree.buf[self->root].color == RBTree_black);
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].color == RBTree_red) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
|
||||
check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
|
||||
}
|
||||
}
|
||||
|
||||
/* checking keys, but better */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(U64Segment_less_by_start(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1]));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(U64Segment_less_by_start(&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) {
|
||||
size_t cur = self->tree.buf[v].left;
|
||||
while (self->tree.buf[cur].right != 0)
|
||||
cur = self->tree.buf[cur].right;
|
||||
check(U64Segment_less_by_start(&self->el.buf[cur - 1], &self->el.buf[v - 1]));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
size_t cur = self->tree.buf[v].right;
|
||||
while (self->tree.buf[cur].left != 0)
|
||||
cur = self->tree.buf[cur].left;
|
||||
check(U64Segment_less_by_start(&self->el.buf[v - 1], &self->el.buf[cur - 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stress_ByStart(){
|
||||
printf("Prepare for some real stress\n");
|
||||
for (int s = 2; s < 800; s++) {
|
||||
srand(s);
|
||||
BuffRBTreeByStart_SetU64Segment set = BuffRBTreeByStart_SetU64Segment_new();
|
||||
VecU64Segment real_set = VecU64Segment_new();
|
||||
U32 n = (U32)s;
|
||||
VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
U64Segment value = {i, (U64)rand()};
|
||||
VecU64Segment_append(&complementary_set, value);
|
||||
}
|
||||
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;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
|
||||
VecU64Segment_append(&real_set, v);
|
||||
check(BuffRBTreeByStart_SetU64Segment_insert(&set, v));
|
||||
check_correctness_ByStart(&set);
|
||||
} else {
|
||||
assert(real_set.len > 0);
|
||||
size_t j = rand() % real_set.len;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
|
||||
VecU64Segment_append(&complementary_set, v);
|
||||
check(BuffRBTreeByStart_SetU64Segment_erase(&set, &v));
|
||||
check_correctness_ByStart(&set);
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
for (size_t j = 0; j < real_set.len; j++) {
|
||||
check(BuffRBTreeByStart_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
|
||||
check(BuffRBTreeByStart_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
|
||||
}
|
||||
for (size_t j = 0; j < complementary_set.len; j++) {
|
||||
check(BuffRBTreeByStart_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
|
||||
check(BuffRBTreeByStart_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
|
||||
}
|
||||
}
|
||||
VecU64Segment_drop(real_set);
|
||||
VecU64Segment_drop(complementary_set);
|
||||
BuffRBTreeByStart_SetU64Segment_drop(set);
|
||||
printf("Seed s=%d passed test\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
void check_correctness_ByLen(const BuffRBTreeByLen_SetU64Segment* self){
|
||||
check(self->tree.len == self->el.len + 1);
|
||||
check(self->root < self->tree.len);
|
||||
if (self->tree.len > 1) {
|
||||
check(self->root != 0);
|
||||
}
|
||||
VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
|
||||
check_structure_h_dfs(self->tree.buf, self->root, &f);
|
||||
for (size_t i = 0; i < self->tree.len - 1; i++) {
|
||||
check(*VecU8_at(&f, i));
|
||||
}
|
||||
VecU8_drop(f); /* f invalidated */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (v == self->root) {
|
||||
check(self->tree.buf[v].parent == 0);
|
||||
} else {
|
||||
check(self->tree.buf[v].parent != 0);
|
||||
}
|
||||
check(self->tree.buf[v].parent < self->tree.len);
|
||||
check(self->tree.buf[v].left < self->tree.len);
|
||||
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);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].right].parent == v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Checking coloring */
|
||||
check(self->tree.buf[0].color == RBTree_black);
|
||||
if (self->root != 0)
|
||||
check(self->tree.buf[self->root].color == RBTree_black);
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].color == RBTree_red) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
|
||||
check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
|
||||
}
|
||||
}
|
||||
|
||||
/* checking keys, but better */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(U64Segment_less_by_len_and_start(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1]));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(U64Segment_less_by_len_and_start(&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) {
|
||||
size_t cur = self->tree.buf[v].left;
|
||||
while (self->tree.buf[cur].right != 0)
|
||||
cur = self->tree.buf[cur].right;
|
||||
check(U64Segment_less_by_len_and_start(&self->el.buf[cur - 1], &self->el.buf[v - 1]));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
size_t cur = self->tree.buf[v].right;
|
||||
while (self->tree.buf[cur].left != 0)
|
||||
cur = self->tree.buf[cur].left;
|
||||
check(U64Segment_less_by_len_and_start(&self->el.buf[v - 1], &self->el.buf[cur - 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stress_ByLen(){
|
||||
printf("Prepare for some real stress\n");
|
||||
for (int s = 2; s < 400; s++) {
|
||||
srand(s);
|
||||
BuffRBTreeByLen_SetU64Segment set = BuffRBTreeByLen_SetU64Segment_new();
|
||||
VecU64Segment real_set = VecU64Segment_new();
|
||||
U32 n = (U32)s;
|
||||
VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
U64Segment value = {i, (U64)rand()};
|
||||
VecU64Segment_append(&complementary_set, value);
|
||||
}
|
||||
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;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
|
||||
VecU64Segment_append(&real_set, v);
|
||||
check(BuffRBTreeByLen_SetU64Segment_insert(&set, v));
|
||||
check_correctness_ByLen(&set);
|
||||
} else {
|
||||
assert(real_set.len > 0);
|
||||
size_t j = rand() % real_set.len;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
|
||||
VecU64Segment_append(&complementary_set, v);
|
||||
check(BuffRBTreeByLen_SetU64Segment_erase(&set, &v));
|
||||
check_correctness_ByLen(&set);
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
for (size_t j = 0; j < real_set.len; j++) {
|
||||
check(BuffRBTreeByLen_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
|
||||
check(BuffRBTreeByLen_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
|
||||
}
|
||||
for (size_t j = 0; j < complementary_set.len; j++) {
|
||||
check(BuffRBTreeByLen_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
|
||||
check(BuffRBTreeByLen_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
|
||||
}
|
||||
}
|
||||
VecU64Segment_drop(real_set);
|
||||
VecU64Segment_drop(complementary_set);
|
||||
BuffRBTreeByLen_SetU64Segment_drop(set);
|
||||
printf("Seed s=%d passed test\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
void check_correctness_ByLenRespAlign(const BuffRBTreeByLenRespAlign_SetU64Segment* self, U8 alignment_exp){
|
||||
check(self->guest == alignment_exp)
|
||||
check(self->tree.len == self->el.len + 1);
|
||||
check(self->root < self->tree.len);
|
||||
if (self->tree.len > 1) {
|
||||
check(self->root != 0);
|
||||
}
|
||||
VecU8 f = VecU8_new_zeroinit(self->tree.len - 1);
|
||||
check_structure_h_dfs(self->tree.buf, self->root, &f);
|
||||
for (size_t i = 0; i < self->tree.len - 1; i++) {
|
||||
check(*VecU8_at(&f, i));
|
||||
}
|
||||
VecU8_drop(f); /* f invalidated */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (v == self->root) {
|
||||
check(self->tree.buf[v].parent == 0);
|
||||
} else {
|
||||
check(self->tree.buf[v].parent != 0);
|
||||
}
|
||||
check(self->tree.buf[v].parent < self->tree.len);
|
||||
check(self->tree.buf[v].left < self->tree.len);
|
||||
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);
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(self->tree.buf[self->tree.buf[v].right].parent == v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Checking coloring */
|
||||
check(self->tree.buf[0].color == RBTree_black);
|
||||
if (self->root != 0)
|
||||
check(self->tree.buf[self->root].color == RBTree_black);
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].color == RBTree_red) {
|
||||
check(self->tree.buf[self->tree.buf[v].left].color == RBTree_black);
|
||||
check(self->tree.buf[self->tree.buf[v].right].color == RBTree_black);
|
||||
}
|
||||
}
|
||||
|
||||
/* checking keys, but better */
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[self->tree.buf[v].left - 1], &self->el.buf[v - 1], alignment_exp));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[v - 1], &self->el.buf[self->tree.buf[v].right - 1], alignment_exp));
|
||||
}
|
||||
}
|
||||
for (size_t v = 1; v < self->tree.len; v++) {
|
||||
if (self->tree.buf[v].left != 0) {
|
||||
size_t cur = self->tree.buf[v].left;
|
||||
while (self->tree.buf[cur].right != 0)
|
||||
cur = self->tree.buf[cur].right;
|
||||
check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[cur - 1], &self->el.buf[v - 1], alignment_exp));
|
||||
}
|
||||
if (self->tree.buf[v].right != 0) {
|
||||
size_t cur = self->tree.buf[v].right;
|
||||
while (self->tree.buf[cur].left != 0)
|
||||
cur = self->tree.buf[cur].left;
|
||||
check(U64Segment_less_by_len_and_start_resp_align(&self->el.buf[v - 1], &self->el.buf[cur - 1], alignment_exp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stress_ByLenRespAlign(U8 alignment_exp){
|
||||
printf("Prepare for some real stress\n");
|
||||
for (int s = 2; s < 400; s++) {
|
||||
srand(s + 232323);
|
||||
BuffRBTreeByLenRespAlign_SetU64Segment set = BuffRBTreeByLenRespAlign_SetU64Segment_new(alignment_exp);
|
||||
VecU64Segment real_set = VecU64Segment_new();
|
||||
U32 n = (U32)s;
|
||||
VecU64Segment complementary_set = VecU64Segment_new_reserved(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
U64Segment value = {i, (U64)rand()};
|
||||
VecU64Segment_append(&complementary_set, value);
|
||||
}
|
||||
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;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&complementary_set, j);
|
||||
VecU64Segment_append(&real_set, v);
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_insert(&set, v));
|
||||
check_correctness_ByLenRespAlign(&set, alignment_exp);
|
||||
} else {
|
||||
assert(real_set.len > 0);
|
||||
size_t j = rand() % real_set.len;
|
||||
U64Segment v = VecU64Segment_unordered_pop(&real_set, j);
|
||||
VecU64Segment_append(&complementary_set, v);
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_erase(&set, &v));
|
||||
check_correctness_ByLenRespAlign(&set, alignment_exp);
|
||||
}
|
||||
/* We did something */
|
||||
check(real_set.len == set.el.len);
|
||||
for (size_t j = 0; j < real_set.len; j++) {
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_find(&set, &real_set.buf[j]) != 0);
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_at(&set, &real_set.buf[j]).variant == Option_Some);
|
||||
}
|
||||
for (size_t j = 0; j < complementary_set.len; j++) {
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_find(&set, &complementary_set.buf[j]) == 0);
|
||||
check(BuffRBTreeByLenRespAlign_SetU64Segment_at(&set, &complementary_set.buf[j]).variant == Option_None);
|
||||
}
|
||||
}
|
||||
VecU64Segment_drop(real_set);
|
||||
VecU64Segment_drop(complementary_set);
|
||||
BuffRBTreeByLenRespAlign_SetU64Segment_drop(set);
|
||||
printf("Seed s=%d passed test\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
stress_ByStart();
|
||||
stress_ByLen();
|
||||
stress_ByLenRespAlign(0); // 1
|
||||
stress_ByLenRespAlign(3); // 8
|
||||
stress_ByLenRespAlign(10); // 1024
|
||||
stress_ByLenRespAlign(12); // 4096
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user