diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c754b..cd27a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ add_executable(codegen_l1_5 src/l1_5/anne/codegen.c) #target_link_libraries(3_render_test -lwayland-client -lm -lvulkan -lxkbcommon) #add_executable(l2t0_2 src/l2/tests/data_structures/t0_2.c) // todo: I will get back +add_executable(l2t0 src/l2/tests/data_structures/t0.c) add_executable(l2t0_3 src/l2/tests/data_structures/t0_3.c) add_executable(l2t2 src/l2/tests/data_structures/t2.c) diff --git a/src/l1/anne/margaret/margaret_misc.h b/src/l1/anne/margaret/margaret_misc.h index a1f0e42..d356c9e 100644 --- a/src/l1/anne/margaret/margaret_misc.h +++ b/src/l1/anne/margaret/margaret_misc.h @@ -36,7 +36,7 @@ void generate_margaret_eve_for_vulkan_utils() { generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){ /* We won't need to clone this type, like, at all... It is actually clonable, but we just made * it non-clonable */ - .T = cstr("BuffRBTreeByLenRespAlign_SetMargaretFreeMemSegment") + .T = cstr("BufRBTreeByLenRespAlign_SetMargaretFreeMemSegment") }); generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){ .T = cstr("MargaretMemAllocatorOneBlock"), .vec = true, diff --git a/src/l1/anne/some_tests.h b/src/l1/anne/some_tests.h index 117e59a..6088aa1 100644 --- a/src/l1/anne/some_tests.h +++ b/src/l1/anne/some_tests.h @@ -38,10 +38,10 @@ void generate_headers_for_r0_r1_r2_r3() { generate_eve_span_company_for_primitive(l, ns, cstr("I_FishNode"), true, false); generate_eve_span_company_for_primitive(l, ns, cstr("J_AlphaVertex"), true, false); } - // mkdir_nofail("l1/eve/ds_test"); - // { /* This structure is needed for testing purposes only */ - // generate_eve_span_company_for_primitive(l, cstr("ds_test"), cstr("RefRBTreeNode_S64"), true, false); - // } + mkdir_nofail("l1/eve/ds_test"); + { /* This structure is needed for testing purposes only */ + generate_eve_span_company_for_primitive(l, cstr("ds_test"), cstr("RefRBTreeNode_S64"), true, false); + } } #endif \ No newline at end of file diff --git a/src/l1_5/anne/margaret.h b/src/l1_5/anne/margaret.h index b8f0cc3..e3b36ad 100644 --- a/src/l1_5/anne/margaret.h +++ b/src/l1_5/anne/margaret.h @@ -2,6 +2,7 @@ #define prototype1_src_l1_5_anne_margaret_h #include "../codegen/buff_rbtree_set_map_template_inst.h" +#include "../codegen/rbtree_set_map_template_inst.h" void generate_l1_5_template_instantiations_for_margaret(){ SpanU8 l = cstr("l1_5"), ns = cstr("margaret"); @@ -10,27 +11,24 @@ void generate_l1_5_template_instantiations_for_margaret(){ /* For MargaretMemAllocator */ generate_buf_rbtree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){ - .T = cstr("MargaretFreeMemSegment"), - .t_primitive = true, + .T = cstr("MargaretFreeMemSegment"), .t_primitive = true, .alternative_less = cstr("MargaretFreeMemSegment_less"), - .alternative_equal = cstr("MargaretFreeMemSegment_equal"), .alternative_comp_set_name_embed = cstr("Len"), }); generate_buf_rbtree_Set_templ_inst_eve_header(l, ns, (set_instantiation_op){ - .T = cstr("MargaretFreeMemSegment"), - .t_primitive = true, + .T = cstr("MargaretFreeMemSegment"), .t_primitive = true, /* comparison takes additional U8 parameter */ .alternative_less = cstr("MargaretFreeMemSegment_less_resp_align"), - .alternative_equal = cstr("MargaretFreeMemSegment_equal_resp_align"), .alternative_comp_set_name_embed = cstr("LenRespAlign"), .guest_data_T = cstr("U8"), }); - // generate_buf_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ - // .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretMemoryOccupation"), /* MargaretMemoryOccupation is not primitive */ - // }); - // generate_buf_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ - // .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretBufferOccupationSubBuffer"), .v_primitive = true, - // }); + generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ + /* MargaretMemoryOccupation is not primitive */ + .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretMemoryOccupation"), + }, true /* We want RBTreeNode_KVPU64ToMargaretMemoryOccupation to be generated here for us */ ); + generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){ + .K = cstr("U64"), .k_integer = true, .V = cstr("MargaretBufferOccupationSubBuffer"), .v_primitive = true, + }, true); } #endif \ No newline at end of file diff --git a/src/l1_5/codegen/all_set_map_templ_util_inst.h b/src/l1_5/codegen/all_set_map_templ_util_inst.h index 64134e4..e6d5872 100644 --- a/src/l1_5/codegen/all_set_map_templ_util_inst.h +++ b/src/l1_5/codegen/all_set_map_templ_util_inst.h @@ -9,7 +9,6 @@ typedef struct { bool t_integer; bool t_primitive; bool t_clonable; - SpanU8 alternative_equal; SpanU8 alternative_less; SpanU8 alternative_comp_set_name_embed; @@ -25,15 +24,8 @@ void set_instantiation_op_fix(set_instantiation_op* self){ if (self->t_primitive) self->t_clonable = true; assert(self->T.len > 0); - assert((self->alternative_less.len == 0 && self->alternative_equal.len == 0 - && self->alternative_comp_set_name_embed.len == 0 - )||( - self->alternative_comp_set_name_embed.len != 0 && - (self->alternative_less.len != 0 || self->alternative_equal.len != 0))); - if (self->guest_data_T.len > 0) { - assert(self->alternative_comp_set_name_embed.len > 0); - assert(self->alternative_equal.len > 0 && self->alternative_less.len > 0); - } + assert(self->alternative_less.len > 0 == self->alternative_comp_set_name_embed.len > 0); + assert(self->guest_data_T.len == 0 || self->alternative_less.len > 0); } /* We assume K and V are trivially movable */ @@ -47,7 +39,6 @@ typedef struct { bool v_primitive; bool v_clonable; - SpanU8 alternative_equal; SpanU8 alternative_less; SpanU8 alternative_comp_map_name_embed; @@ -67,15 +58,41 @@ void map_instantiation_op_fix(map_instantiation_op* self){ self->v_primitive = true; if (self->v_primitive) self->v_clonable = true; - assert((self->alternative_less.len == 0 && self->alternative_equal.len == 0 - && self->alternative_comp_map_name_embed.len == 0 - )||( - self->alternative_comp_map_name_embed.len != 0 && - (self->alternative_less.len != 0 || self->alternative_equal.len != 0))); - if (self->guest_data_T.len > 0) { - assert(self->alternative_comp_map_name_embed.len > 0); - assert(self->alternative_equal.len > 0 && self->alternative_less.len > 0); - } + assert(self->alternative_less.len > 0 == self->alternative_comp_map_name_embed.len > 0); + assert(self->guest_data_T.len == 0 || self->alternative_less.len > 0); } + +/* --- Sharing is caring --- */ +/* Assuming A nd B are passed as intended */ +NODISCARD VecU8 codegen_rbtree_map__less(map_instantiation_op op, VecU8 A, VecU8 B){ + if (op.guest_data_T.len > 0) { + assert(op.alternative_less.len > 0); + return VecU8_fmt("%s(%v, %v, self->guest)", op.alternative_less, A, B); + } + if (op.alternative_less.len > 0) + return VecU8_fmt("%s(%v, %v)", op.alternative_less, A, B); + if (op.k_integer) + return VecU8_fmt("%v < %v", A, B); + return VecU8_fmt("%s_less_%s(%v %v)", op.K, op.K, A, B); +} + +NODISCARD VecU8 codegen_rbtree_map__exp_passing_key_val(map_instantiation_op op){ + return op.k_integer ? vcstr("key") : vcstr("&key"); +} + +/* Suppose some method (like _erase() or _pop(), or _find(), or _at(), takes constant reference to key T + * This function tells how to write type of this argument. Basically it is needed to take into account that + * integer is better than pointer to integer. (Though, notice that _pop family of methods don't exist for + * sets of integers + */ +NODISCARD VecU8 codegen_rbtree_map__taking_ref_k_argument(map_instantiation_op op){ + return op.k_integer ? VecU8_from_span(op.K) : VecU8_fmt("const %s*", op.K); +} + +NODISCARD VecU8 codegen_rbtree_map__taking_t_argument(map_instantiation_op op){ + return op.V.len > 0 ? VecU8_fmt("%s key, %s value", op.K, op.V) : VecU8_fmt("%s key", op.K); +} + + #endif diff --git a/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h b/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h index 65f2347..7a80f0c 100644 --- a/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h +++ b/src/l1_5/codegen/buff_rbtree_set_map_template_inst.h @@ -3,114 +3,13 @@ #include "all_set_map_templ_util_inst.h" -SpanU8 codegen_buff_rbtree_map__key_of_cur_el(map_instantiation_op op){ - return op.V.len > 0 ? cstr("self->el.buf[cur - 1].key") : cstr("self->el.buf[cur - 1]"); +/* Assuming A nd B are passed as intended */ + +NODISCARD VecU8 codegen_buf_rbtree_map__exp_passing_cur_key(map_instantiation_op op){ + return VecU8_fmt("%s" "self->el.buf[cur - 1]" "%s", + op.k_integer ? cstr("") : cstr("&"), op.V.len > 0 ? cstr(".key") : cstr("")); } -/* When key is given by value into some method of Buff_RBTreeSet */ -NODISCARD VecU8 codegen_buff_rbtree_map__key_value_NOT_EQUAL_element(map_instantiation_op op){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_equal.len > 0); - if (op.k_integer) - return VecU8_fmt("!%s(key, %s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s(&key, &%s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.alternative_equal.len > 0) { - if (op.k_integer) - return VecU8_fmt("!%s(key, %s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s(&key, &%s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.k_integer) - return VecU8_fmt("key != %s", codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s_equal_%s(&key, &%s)", op.K, op.K, codegen_buff_rbtree_map__key_of_cur_el(op)); -} - -/* When key is given by value into some method of Buff_RBTreeSet */ -NODISCARD VecU8 codegen_buff_rbtree_map__key_value_LESS_element(map_instantiation_op op){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_less.len > 0); - if (op.k_integer) - return VecU8_fmt("%s(key, %s, self->guest)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(&key, &%s, self->guest)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.alternative_less.len > 0) { - if (op.k_integer) - return VecU8_fmt("%s(key, %s)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(&key, &%s)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.k_integer) - return VecU8_fmt("key < %s", codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s_less_%s(&key, &%s)", op.K, op.K, codegen_buff_rbtree_map__key_of_cur_el(op)); -} - -/* When key is given by ref into some method of Buff_RBTreeSet - * Ofk when op.T is integer, argument is still taken by a value */ -NODISCARD VecU8 codegen_buff_rbtree_map__key_ref_NOT_EQUAL_element(map_instantiation_op op){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_equal.len > 0); - if (op.k_integer) - return VecU8_fmt("!%s(key, %s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s(key, &%s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.alternative_equal.len > 0) { - if (op.k_integer) - return VecU8_fmt("!%s(key, %s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s(key, &%s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.k_integer) - return VecU8_fmt("key != %s", codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("!%s_equal_%s(key, &%s)", op.K, op.K, codegen_buff_rbtree_map__key_of_cur_el(op)); -} - -/* When key is given by a pointer into some method of Buff_RBTreeSet */ -NODISCARD VecU8 codegen_buff_rbtree_map__key_ref_EQUAL_element(map_instantiation_op op){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_equal.len > 0); - if (op.k_integer) - return VecU8_fmt("%s(key, %s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(key, &%s, self->guest)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.alternative_equal.len > 0) { - if (op.k_integer) - return VecU8_fmt("%s(key, %s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(key, &%s)", op.alternative_equal, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.k_integer) - return VecU8_fmt("key == %s", codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s_equal_%s(key, &%s)", op.K, op.K, codegen_buff_rbtree_map__key_of_cur_el(op)); -} - -/* When key is given by a pointer into some method of Buff_RBTreeSet */ -NODISCARD VecU8 codegen_buff_rbtree_map__key_ref_LESS_element(map_instantiation_op op){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_less.len > 0); - if (op.k_integer) - return VecU8_fmt("%s(key, %s, self->guest)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(key, &%s, self->guest)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.alternative_less.len > 0) { - if (op.k_integer) - return VecU8_fmt("%s(key, %s)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s(key, &%s)", op.alternative_less, codegen_buff_rbtree_map__key_of_cur_el(op)); - } - if (op.k_integer) - return VecU8_fmt("key < %s", codegen_buff_rbtree_map__key_of_cur_el(op)); - return VecU8_fmt("%s_less_%s(key, &%s)", op.K, op.K, codegen_buff_rbtree_map__key_of_cur_el(op)); -} - - -/* Suppose some method (like _erase() or _pop(), or _find(), or _at(), takes constant reference to key T - * This function tells how to write type of this argument. Basically it is needed to take into account that - * integer is better than pointer to integer. (Though, notice that _pop family of methods don't exist for - * sets of integers - */ -NODISCARD VecU8 codegen_buff_rbtree_map__taking_ref_k_argument(map_instantiation_op op){ - return op.k_integer ? VecU8_from_span(op.K) : VecU8_fmt("const %s*", op.K); -} - -NODISCARD VecU8 codegen_buff_rbtree_map__taking_t_argument(map_instantiation_op op){ - return op.V.len > 0 ? VecU8_fmt("%s key, %s value", op.K, op.V) : VecU8_fmt("%s key", op.K); -} /* Yes, both sets and maps use this function to instantiate themselves. No, user does not need to use it * set is either a set name or a map name. If we are instantiating set, TT is op.T from set options, if we are @@ -176,20 +75,19 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods( VecU8_append_vec(res, VecU8_fmt( "U64 %s_find(const %s* self, %v key) {\n" /* set, set, taking_ref_k_argument */ SPACE "U64 cur = self->root;\n" - SPACE "while (cur != 0 && %v) {\n" /* key reference not equal cur element */ - SPACE SPACE "if (%v) {\n" /* key reference less than cur element */ + SPACE "while (cur != 0) {\n" + SPACE SPACE "if (%v)\n" /* key < cur key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" + SPACE SPACE "else if (%v)\n" /* cur key < key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" - SPACE SPACE "}\n" + SPACE SPACE "else \n" + SPACE SPACE SPACE "return cur;\n" SPACE "}\n" - SPACE "return cur;\n" + SPACE "return 0;\n" "}\n\n", - set, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_NOT_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op) - )); - + set, set, codegen_rbtree_map__taking_ref_k_argument(op), + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")))); if (op.k_clonable && op.v_clonable) { VecU8_append_vec(res, VecU8_fmt( @@ -218,7 +116,7 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods( SPACE "}\n" "}\n\n", set, set)); - // todo: move to comon code + // todo: move to comon code (core/buff_rb_tree_node.h) VecU8_append_vec(res, VecU8_fmt( "U64 %s_find_prev(const %s* self, U64 x){\n" SPACE "assert(x != 0 && x < self->tree.len);\n" @@ -249,73 +147,71 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods( SPACE "U64 last_less = 0;\n" SPACE "U64 cur = self->root;\n" SPACE "while (cur != 0) {\n" - SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */ + SPACE SPACE "if (%v) {" /* key < cur key */ + SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" + SPACE SPACE "} else if (%v) {\n" /* cur key < key */ + SPACE SPACE SPACE "last_less = cur;\n" + SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE "} else {\n" SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" SPACE SPACE SPACE "if (cur == 0)\n" SPACE SPACE SPACE SPACE "return last_less;\n" SPACE SPACE SPACE "while (self->tree.buf[cur].right != 0)\n" SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" SPACE SPACE SPACE "return cur;\n" - SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */ - SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" - SPACE SPACE SPACE "last_less = cur;\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" SPACE SPACE "}\n" SPACE "}\n" SPACE "return last_less;\n" "}\n\n", - set, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op) - )); + set, set, codegen_rbtree_map__taking_ref_k_argument(op), + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")))); VecU8_append_vec(res, VecU8_fmt( "U64 %s_find_max_less_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */ SPACE "U64 last_less = 0;\n" SPACE "U64 cur = self->root;\n" SPACE "while (cur != 0) {\n" - SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */ - SPACE SPACE SPACE "return cur;\n" - SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */ + SPACE SPACE "if (%v) {" /* key < cur key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" + SPACE SPACE "} else if (%v) {\n" /* cur key < key */ SPACE SPACE SPACE "last_less = cur;\n" SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE "} else {\n" + SPACE SPACE SPACE "return cur;\n" SPACE SPACE "}\n" SPACE "}\n" SPACE "return last_less;\n" "}\n\n", - set, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op) - )); + set, set, codegen_rbtree_map__taking_ref_k_argument(op), + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")))); + VecU8_append_vec(res, VecU8_fmt( "U64 %s_find_min_grtr(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */ SPACE "U64 last_grtr = 0;\n" SPACE "U64 cur = self->root;\n" SPACE "while (cur != 0) {\n" - SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */ + SPACE SPACE "if (%v) {\n" /* key < cur key*/ + SPACE SPACE SPACE "last_grtr = cur;\n" + SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" + SPACE SPACE "} else if (%v) {\n" /* cur key < key */ + SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE "} else {\n" SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" SPACE SPACE SPACE "if (cur == 0)\n" SPACE SPACE SPACE SPACE "return last_grtr;\n" SPACE SPACE SPACE "while (self->tree.buf[cur].left != 0)\n" SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" SPACE SPACE SPACE "return cur;\n" - SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */ - SPACE SPACE SPACE "last_grtr = cur;\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" SPACE SPACE "}\n" SPACE "}\n" SPACE "return last_grtr;\n" "}\n\n", - set, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op) - )); + set, set, codegen_rbtree_map__taking_ref_k_argument(op), + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")))); VecU8_append_vec(res, VecU8_fmt( @@ -323,187 +219,150 @@ void codegen_append_buff_rbtree_map__structure_and_simplest_methods( SPACE "U64 last_grtr = 0;\n" SPACE "U64 cur = self->root;\n" SPACE "while (cur != 0) {\n" - SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */ - SPACE SPACE SPACE "return cur;\n" - SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */ + SPACE SPACE "if (%v) {\n" /* key < cur key*/ SPACE SPACE SPACE "last_grtr = cur;\n" SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" + SPACE SPACE "} else if (%v) {\n" /* cur key < key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE "} else {\n" + SPACE SPACE SPACE "return cur;\n" SPACE SPACE "}\n" SPACE "}\n" SPACE "return last_grtr;\n" "}\n\n", - set, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op) - )); -} - - -// todo: no need for a separate method. Just write _try_insert() and derive all the shit from it -void codegen_append_buf_rbtree_map__insert_kind_method( - VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT, VecU8 Tc, VecU8 Fc - ){ - VecU8 Tc_root = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 2); - VecU8 Tc_on_left = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4); - VecU8 Tc_on_right = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4); - VecU8 Fc_exists = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 1); - VecU8_drop(Tc); - VecU8_drop(Fc); - - // todo: fix it. No buffered rbttrees here. Only my pure poijter basa[ks tree + set, set, codegen_rbtree_map__taking_ref_k_argument(op), + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")))); VecU8 line_that_appends_new_el_to_el_vec = op.V.len > 0 ? VecU8_fmt("VecKVP%sTo%s_append(&self->el, (KVP%sTo%s){.key = key, .value = value});", op.K, op.V, op.K, op.V) : VecU8_fmt("Vec%s_append(&self->el, key);", op.K); VecU8_append_vec(res, VecU8_fmt( - "%v %s_%s(%s* self, %v) {\n" /* RT, set, method_name, set, taking_t_argument */ - SPACE "if (self->root == 0) {\n" - SPACE SPACE "assert(self->tree.len == 1);\n" - SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.color = RBTree_black});\n" - SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ - SPACE SPACE "self->root = 1;\n" - "%v" /* Tc_root */ - /* Should have returned by now in Tc*/ - SPACE "}\n" - SPACE "U64 cur = self->root;\n" - SPACE "while (%v) {\n" /* el[cur] != key */ - SPACE SPACE "if (%v) {\n" /* key < el[cur] */ - SPACE SPACE SPACE "if (self->tree.buf[cur].left != 0) {\n" - SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE SPACE "} else { \n" - /* We are inserting to the left of cur */ - SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n" - SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n" - SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n" - SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n" - SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ - "%v" /* Tc_on_left */ - /* Should have returned by now in Tc*/ - SPACE SPACE SPACE "}\n" - SPACE SPACE "} else {\n" - SPACE SPACE SPACE "if (self->tree.buf[cur].right != 0) {\n" - SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" - SPACE SPACE SPACE "} else {\n" - /* We are inserting to the right of cur */ - SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n" - SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n" - SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n" - SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n" - SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ - "%v" /* Tc_on_right */ - /* Should have returned by now in Tc*/ - SPACE SPACE SPACE "}\n" - SPACE SPACE "}\n" - SPACE "}\n" - "%v" /* Fc_exists */ - /* Should have returned by now in Tc*/ - "}\n\n", - RT, set, method_name, set, codegen_buff_rbtree_map__taking_t_argument(op), - VecU8_to_span(&line_that_appends_new_el_to_el_vec), // !! - Tc_root, - codegen_buff_rbtree_map__key_value_NOT_EQUAL_element(op), - codegen_buff_rbtree_map__key_value_LESS_element(op), - VecU8_to_span(&line_that_appends_new_el_to_el_vec), - Tc_on_left, - VecU8_to_span(&line_that_appends_new_el_to_el_vec), - Tc_on_right, - Fc_exists - )); - - VecU8_drop(line_that_appends_new_el_to_el_vec); -} - -// todo: no need for a separate function. Do just like in normal RBTree -void codegen_append_buff_rbtree_map__method_empty_index_erase(VecU8* res, SpanU8 set){ - VecU8_append_vec(res, VecU8_fmt( - "/* UNSAFE. Use when you dropped the symbol that is about to be deleted */\n" - "void %s_empty_index_erase(%s* self, U64 z) {\n" /* set, set */ - SPACE "assert(z != 0 && z < self->tree.len);\n" - SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : BufRBTree_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 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[x_adopter].left == y)\n" - SPACE SPACE "self->tree.buf[x_adopter].left = x;\n" - SPACE "else\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 SPACE "BufRBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\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 "BufRBTree_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 "BufRBTree_fix_after_delete(self->tree.buf, &self->root, x);\n" - "}\n\n", - set, set)); -} - -// todo: no need for a separate method. -void codegen_append_buff_rbtree_map__erase_kind_method( - VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT, - VecU8 Fc, VecU8 Tc_cur_available, VecU8 Tc_returning - ){ - VecU8 not_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 3); - VecU8 saving_prev = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_cur_available), 1); - VecU8 ret_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_returning), 1); - VecU8_drop(Fc); - VecU8_drop(Tc_cur_available); - VecU8_drop(Tc_returning); + /* This method is unsafe. Arguments key, value will be taken if 0 is returned, + * or left on their place if not-0 is returned */ + "/* UNSAFE */\n" + "NODISCARD U64 %s_try_insert(%s* self, %v) {\n" /* set, set, taking_t_argument */ + SPACE "if (self->root == 0) {\n" + SPACE SPACE "assert(self->tree.len == 1);\n" + SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.color = RBTree_black});\n" + SPACE SPACE "self->root = 1;\n" + SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ + SPACE SPACE "return 0;\n" + SPACE "}\n" + SPACE "U64 cur = self->root;\n" + SPACE "while (true) {\n" + SPACE SPACE "if (%v) {\n" /* key < el[cur] */ + SPACE SPACE SPACE "if (self->tree.buf[cur].left != 0) {\n" + SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" + SPACE SPACE SPACE "} else { \n" + SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n" + SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n" + SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n" + SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n" + SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ + SPACE SPACE SPACE SPACE "return 0;\n" + SPACE SPACE SPACE "}\n" + SPACE SPACE "} else if (%v) {\n" /* el[cur] < key */ + SPACE SPACE SPACE "if (self->tree.buf[cur].right != 0) {\n" + SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE SPACE "} else {\n" + SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n" + SPACE SPACE SPACE SPACE "VecBufRBTreeNode_append(&self->tree, (BufRBTreeNode){.parent = cur, .color = RBTree_red});\n" + SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n" + SPACE SPACE SPACE SPACE "BufRBTree_fix_after_insert(self->tree.buf, &self->root, n);\n" + SPACE SPACE SPACE SPACE "%s\n" /* line_that_appends_new_el_to_el_vec */ + SPACE SPACE SPACE SPACE "return 0;\n" + SPACE SPACE SPACE "}\n" + SPACE SPACE "} else {\n" + SPACE SPACE SPACE "return cur;\n" + SPACE SPACE "}\n" + SPACE "}\n" + "}\n\n", + set, set, codegen_rbtree_map__taking_t_argument(op), + VecU8_to_span(&line_that_appends_new_el_to_el_vec), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_val(op), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + VecU8_to_span(&line_that_appends_new_el_to_el_vec), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_val(op)), + VecU8_to_span(&line_that_appends_new_el_to_el_vec))); + VecU8_drop(line_that_appends_new_el_to_el_vec); VecU8_append_vec(res, VecU8_fmt( - "%v %s_%s(%s* self, %v key) {\n" /* RT, set, method_name, set, taking_ref_t_argument */ - SPACE "U64 cur = self->root;\n" - SPACE "while (true){\n" - SPACE SPACE "if (cur == 0) {\n" - "%v" /* not_found_case */ - SPACE SPACE "}\n" - SPACE SPACE "if (%v)\n" /* key_ref_EQUAL_element */ - SPACE SPACE SPACE "break;\n" - SPACE SPACE "if (%v)\n" /* key_ref_LESS_element */ - SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "else\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" - SPACE "}\n" - "%v" /* saving_prev */ - SPACE "%s_empty_index_erase(self, cur);\n" /* set */ - "%v" /* ret_found_case */ - "}\n\n", - RT, set, method_name, set, codegen_buff_rbtree_map__taking_ref_k_argument(op), - not_found_case, - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__key_ref_LESS_element(op), - saving_prev, - set, - ret_found_case)); + "/* UNSAFE. Use when you dropped the symbol that is about to be deleted */\n" + "void %s_empty_index_erase(%s* self, U64 z) {\n" /* set, set */ + SPACE "assert(z != 0 && z < self->tree.len);\n" + SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : BufRBTree_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 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[x_adopter].left == y)\n" + SPACE SPACE "self->tree.buf[x_adopter].left = x;\n" + SPACE "else\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 SPACE "BufRBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\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 "BufRBTree_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 "BufRBTree_fix_after_delete(self->tree.buf, &self->root, x);\n" + "}\n\n", + set, set)); + + VecU8_append_vec(res, VecU8_fmt( + "bool %s_insert(%s* self, %v) {\n" /* set, set, taking_t_argument */ + SPACE "U64 col = %s_try_insert(self, key" "%s" ");\n" /* set, "" /, value */ + SPACE "if (col == 0)\n" + SPACE SPACE "return true;\n" + "%v" "%v" /* "" / dropping key, "" / dropping value */ + SPACE "return false;\n" + "}\n\n", + set, set, codegen_rbtree_map__taking_t_argument(op), + set, op.V.len > 0 ? cstr(", value") : cstr(""), + op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(key);\n", op.K), + op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(value);\n", op.V))); + + VecU8_append_vec(res, VecU8_fmt( + "bool %s_erase(%s* self, %v key) {\n" /* set, set, taking_ref_k_argument */ + SPACE "U64 v = %s_find(self, key);\n" /* set */ + SPACE "if (v == 0)\n" + SPACE SPACE "return false;\n" + "%v" /* "" / op.K_drop(v->key) */ + "%v" /* "" / op.V_drop(v->value) */ + SPACE "%s_empty_index_erase(self, v);\n" /* set */ + SPACE "return true;\n" + "}\n\n", + set, set, codegen_rbtree_map__taking_ref_k_argument(op), set, + op.k_primitive ? vcstr("") : VecU8_fmt( + SPACE "%s_drop(self->el.buf[v - 1]%s);\n", op.K, op.V.len > 0 ? cstr(".key") : cstr("")), + op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(self->el.buf[v - 1].value);\n", op.V), + set )); } -NODISCARD VecU8 codegen_buff_rbtree_map__option_returned_ref_v(map_instantiation_op op, bool mut){ +NODISCARD VecU8 codegen_buf_rbtree_map__option_returned_ref_v(map_instantiation_op op, bool mut){ assert(op.V.len > 0); if (op.v_integer) return VecU8_fmt("Option%s", op.V); return mut ? VecU8_fmt("OptionRefMut%s", op.V) : VecU8_fmt("OptionRef%s", op.V); } -NODISCARD VecU8 codegen_buff_rbtree_map__some_ref_v(map_instantiation_op op, bool mut){ +NODISCARD VecU8 codegen_buf_rbtree_map__some_ref_v(map_instantiation_op op, bool mut){ assert(op.V.len > 0); if (op.v_integer) return VecU8_fmt("Some_%s(self->el.buf[cur - 1].value)", op.V); @@ -512,45 +371,45 @@ NODISCARD VecU8 codegen_buff_rbtree_map__some_ref_v(map_instantiation_op op, boo return VecU8_fmt("Some_Ref%s(&self->el.buf[cur - 1].value)", op.V); } -NODISCARD VecU8 codegen_buff_rbtree_map__none_ref_v(map_instantiation_op op, bool mut){ +NODISCARD VecU8 codegen_buf_rbtree_map__none_ref_v(map_instantiation_op op, bool mut){ assert(op.V.len > 0); if (op.v_integer) return VecU8_fmt("None_%s()", op.V); return mut ? VecU8_fmt("None_RefMut%s()", op.V) : VecU8_fmt("None_Ref%s()", op.V) ; } -void codegen_append_buff_rbtree_map__method_at(VecU8* res, map_instantiation_op op, SpanU8 set, bool mut){ +void codegen_append_buf_rbtree_map__method_at(VecU8* res, map_instantiation_op op, SpanU8 set, bool mut){ VecU8_append_vec(res, VecU8_fmt( "%v %s_%s(%s%s* self, %v key) {\n" /* option_returned_ref_t, set, mat/at, e/const, set, taking_ref_t_argument */ SPACE "U64 cur = self->root;\n" SPACE "while (cur != 0) {\n" - SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */ - SPACE SPACE SPACE "return %v;\n" /* some_ref_t */ - SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */ + SPACE SPACE "if (%v) {\n" /* key < cur key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "} else {\n" + SPACE SPACE "} else if (%v) {\n" /* cur key < key */ SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE SPACE "} else {\n" + SPACE SPACE SPACE "return %v;\n" /* some_ref_t */ SPACE SPACE "}\n" SPACE "}\n" SPACE "return %v;\n" /* none_ref_t */ "}\n\n", - codegen_buff_rbtree_map__option_returned_ref_v(op, mut), set, mut ? cstr("mat") : cstr("at"), - mut ? cstr("") : cstr("const "), set, codegen_buff_rbtree_map__taking_ref_k_argument(op), + codegen_buf_rbtree_map__option_returned_ref_v(op, mut), set, mut ? cstr("mat") : cstr("at"), + mut ? cstr("") : cstr("const "), set, codegen_rbtree_map__taking_ref_k_argument(op), - codegen_buff_rbtree_map__key_ref_EQUAL_element(op), - codegen_buff_rbtree_map__some_ref_v(op, mut), - codegen_buff_rbtree_map__key_ref_LESS_element(op), - codegen_buff_rbtree_map__none_ref_v(op, mut) + codegen_rbtree_map__less(op, vcstr("key"), codegen_buf_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_buf_rbtree_map__exp_passing_cur_key(op), vcstr("key")), + codegen_buf_rbtree_map__some_ref_v(op, mut), + codegen_buf_rbtree_map__none_ref_v(op, mut) )); } NODISCARD VecU8 get_name_of_buf_rbtree_set_structure(set_instantiation_op op){ if (op.alternative_comp_set_name_embed.len) - return VecU8_fmt("BuffRBTreeBy%s_Set%s", op.alternative_comp_set_name_embed, op.T); - return VecU8_fmt("BuffRBTree_Set%s", op.T); + return VecU8_fmt("BufRBTreeBy%s_Set%s", op.alternative_comp_set_name_embed, op.T); + return VecU8_fmt("BufRBTree_Set%s", op.T); } -/* src/l1_5/core/rb_tree_node.h is a dependency of all instantiations of rb_tree_set template +/* src/l1_5/core/buff_rb_tree_node.h is a dependency of all instantiations of BufRBTree_Set template * Don't forget to include them * */ NODISCARD VecU8 generate_buf_rbtree_Set_template_instantiation(set_instantiation_op op){ @@ -562,30 +421,12 @@ NODISCARD VecU8 generate_buf_rbtree_Set_template_instantiation(set_instantiation map_instantiation_op map_op = {.K = op.T, .k_integer = op.t_integer, .k_primitive = op.t_primitive, .k_clonable = op.t_clonable, .V = cstr(""), .v_primitive = true, .v_clonable = true, - .alternative_equal = op.alternative_equal, .alternative_less = op.alternative_less, + .alternative_less = op.alternative_less, .alternative_comp_map_name_embed = op.alternative_comp_set_name_embed, .guest_data_T = op.guest_data_T, }; codegen_append_buff_rbtree_map__structure_and_simplest_methods(&res, map_op, set, op.T); - /* Method _insert() does not try to replace the existing element with equal key, - * it returns true if insertion was done, false if collision happened and key was not inserted */ - codegen_append_buf_rbtree_map__insert_kind_method(&res, map_op, set, cstr("insert"), vcstr("bool"), - vcstr("return true;\n"), - op.t_primitive ? - vcstr("return false;\n") : - VecU8_fmt( - "%s_drop(key);\n" /* op.T */ - "return false;\n", - op.T)); - - codegen_append_buff_rbtree_map__method_empty_index_erase(&res, set); - - codegen_append_buff_rbtree_map__erase_kind_method(&res, map_op, set, cstr("erase"), vcstr("bool"), - vcstr("return false;\n"), - op.t_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1]);\n", op.T), - vcstr("return true;\n")); - VecU8_append_vec(&res, VecU8_fmt( "const %s* %s_at_iter(const %s* self, U64 it) {\n" /* op.T, set, set */ SPACE "assert(0 < it && it < self->tree.len);\n" @@ -631,8 +472,8 @@ void codegen_append_buff_rbtree_map__method_at_iter(VecU8* res, map_instantiatio NODISCARD VecU8 get_name_of_buf_rbtree_map_structure(map_instantiation_op op){ if (op.alternative_comp_map_name_embed.len) - return VecU8_fmt("BuffRBTreeBy%s_Map%sTo%s", op.alternative_comp_map_name_embed, op.K, op.V); - return VecU8_fmt("BuffRBTree_Map%sTo%s", op.K, op.V); + return VecU8_fmt("BufRBTreeBy%s_Map%sTo%s", op.alternative_comp_map_name_embed, op.K, op.V); + return VecU8_fmt("BufRBTree_Map%sTo%s", op.K, op.V); } NODISCARD VecU8 generate_buf_rbtree_Map_template_instantiation(map_instantiation_op op){ @@ -646,55 +487,42 @@ NODISCARD VecU8 generate_buf_rbtree_Map_template_instantiation(map_instantiation codegen_append_buff_rbtree_map__structure_and_simplest_methods(&res, op, map, VecU8_to_span(&kvp_g)); VecU8_drop(kvp_g); - codegen_append_buf_rbtree_map__insert_kind_method(&res, op, map, cstr("insert"), vcstr("bool"), - vcstr("return true;\n"), - VecU8_fmt("%v%v" "return false;\n", - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(key);\n", op.K), - op.v_primitive ? vcstr("") : VecU8_fmt("%s_drop(value);\n", op.V))); + // todo: write erase_substitute (only if v is not primitive) using try_insert + // todo: write pop_substitute using try_insert - codegen_append_buf_rbtree_map__insert_kind_method(&res, op, map, cstr("erase_substitute"), vcstr("bool"), - vcstr("return true;\n"), - VecU8_fmt("%v%v" - "self->el.buf[cur - 1].key = key;\n" - "self->el.buf[cur - 1].value = value;\n" - "return false;\n", - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].value);\n", op.V) - )); + // codegen_append_buf_rbtree_map__insert_kind_method(&res, op, map, cstr("erase_substitute"), vcstr("bool"), + // vcstr("return true;\n"), + // VecU8_fmt("%v%v" + // "self->el.buf[cur - 1].key = key;\n" + // "self->el.buf[cur - 1].value = value;\n" + // "return false;\n", + // op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), + // op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].value);\n", op.V) + // )); + // + // codegen_append_buf_rbtree_map__insert_kind_method(&res, op, map, cstr("pop_substitute"), + // VecU8_fmt("Option%s", op.V), + // VecU8_fmt("return None_%s();\n", op.V), + // VecU8_fmt( + // "%v" "self->el.buf[cur - 1].key = key;\n" /**/ + // "%s saved = self->el.buf[cur - 1].value;\n" /* op.V */ + // "self->el.buf[cur - 1].value = value;\n" + // "return Some_%s(saved);\n", /* op.V */ + // op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), + // op.V, op.V)); - codegen_append_buf_rbtree_map__insert_kind_method(&res, op, map, cstr("pop_substitute"), - VecU8_fmt("Option%s", op.V), - VecU8_fmt("return None_%s();\n", op.V), - VecU8_fmt( - "%v" "self->el.buf[cur - 1].key = key;\n" /**/ - "%s saved = self->el.buf[cur - 1].value;\n" /* op.V */ - "self->el.buf[cur - 1].value = value;\n" - "return Some_%s(saved);\n", /* op.V */ - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), - op.V, op.V)); + // todo: write _pop() using _erase_empty_by_index() + // codegen_append_buff_rbtree_map__erase_kind_method(&res, op, map, cstr("pop"), + // VecU8_fmt("Option%s", op.V), + // VecU8_fmt("return None_%s();\n", op.V), + // VecU8_fmt("%v" "%s saved = self->el.buf[cur - 1].value;\n", + // op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), + // op.V), + // VecU8_fmt("return Some_%s(saved);\n", op.V)); - /* Erasing time!!!! */ - codegen_append_buff_rbtree_map__method_empty_index_erase(&res, map); - - codegen_append_buff_rbtree_map__erase_kind_method(&res, op, map, cstr("erase"), vcstr("bool"), - vcstr("return false;\n"), - VecU8_fmt("%v%v", - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), - op.v_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].value);\n", op.V)), - vcstr("return true;\n")); - - codegen_append_buff_rbtree_map__erase_kind_method(&res, op, map, cstr("pop"), - VecU8_fmt("Option%s", op.V), - VecU8_fmt("return None_%s();\n", op.V), - VecU8_fmt("%v" "%s saved = self->el.buf[cur - 1].value;\n", - op.k_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1].key);\n", op.K), - op.V), - VecU8_fmt("return Some_%s(saved);\n", op.V)); - /* We erased enough */ - - codegen_append_buff_rbtree_map__method_at(&res, op, map, false); - codegen_append_buff_rbtree_map__method_at(&res, op, map, true); + codegen_append_buf_rbtree_map__method_at(&res, op, map, false); + codegen_append_buf_rbtree_map__method_at(&res, op, map, true); /* These functions break my design and return answer through pointers given in arguments. For greater good ofk */ codegen_append_buff_rbtree_map__method_at_iter(&res, op, map, false); diff --git a/src/l1_5/codegen/rbtree_set_map_template_inst.h b/src/l1_5/codegen/rbtree_set_map_template_inst.h index 9dc861f..4409996 100644 --- a/src/l1_5/codegen/rbtree_set_map_template_inst.h +++ b/src/l1_5/codegen/rbtree_set_map_template_inst.h @@ -23,40 +23,11 @@ NODISCARD VecU8 codegen_rbtree__node_structure(map_instantiation_op op){ return res; } -NODISCARD VecU8 codegen_rbtree_map__key_of_cur_el(map_instantiation_op op){ - return VecU8_fmt("((%v *)cur)->key", codegen_rbtree__node_struct_name(op)); -} - -/* Assuming A nd B are passed as intended */ -NODISCARD VecU8 codegen_rbtree_map__less(map_instantiation_op op, VecU8 A, VecU8 B){ - if (op.guest_data_T.len > 0) { - assert(op.alternative_equal.len > 0); - return VecU8_fmt("%s(%v, %v, self->guest)", op.alternative_less, A, B); - } - if (op.alternative_equal.len > 0) - return VecU8_fmt("%s(%v, %v)", op.alternative_less, A, B); - if (op.k_integer) - return VecU8_fmt("%v < %v", A, B); - return VecU8_fmt("%s_less_%s(%v %v)", op.K, op.K, A, B); -} - -NODISCARD VecU8 codegen_rbtree_map__exp_passing_key_ref(map_instantiation_op op){ - return op.k_integer ? vcstr("key") : vcstr("&key"); -} NODISCARD VecU8 codegen_rbtree_map__exp_passing_cur_key(map_instantiation_op op){ return VecU8_fmt("%s" "((%v*)cur)->key", op.k_integer ? cstr("") : cstr("&"), codegen_rbtree__node_struct_name(op)); } - -NODISCARD VecU8 codegen_rbtree_map__taking_ref_k_argument(map_instantiation_op op){ - return op.k_integer ? VecU8_from_span(op.K) : VecU8_fmt("const %s*", op.K); -} - -NODISCARD VecU8 codegen_rbtree_map__taking_t_argument(map_instantiation_op op){ - return op.V.len > 0 ? VecU8_fmt("%s key, %s value", op.K, op.V) : VecU8_fmt("%s key", op.K); -} - void codegen_append_rbtree_map__structure_and_simplest_methods( VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 TT ){ @@ -147,8 +118,8 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return NULL;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_ref(op), codegen_rbtree_map__exp_passing_cur_key(op)), - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_ref(op)), + codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), TT)); VecU8_append_vec(res, VecU8_fmt( @@ -173,8 +144,8 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return last_less;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_ref(op), codegen_rbtree_map__exp_passing_cur_key(op)), - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_ref(op)), + codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), TT, TT)); VecU8_append_vec(res, VecU8_fmt( @@ -194,8 +165,8 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return last_less;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_ref(op), codegen_rbtree_map__exp_passing_cur_key(op)), - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_ref(op)), + codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), TT, TT)); VecU8_append_vec(res, VecU8_fmt( @@ -220,9 +191,9 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return last_grtr;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_ref(op), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_ref(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), TT)); @@ -243,11 +214,12 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return last_grtr;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_ref_k_argument(op), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_ref(op), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), TT, - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_ref(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), TT)); + // todo: implement it like i deed in BufRBTree VecU8_append_vec(res, VecU8_fmt( /* This method is unsafe. Arguments key, value will be taken if 0 is returned, * or left on their place if not-0 is returned */ @@ -277,8 +249,8 @@ void codegen_append_rbtree_map__structure_and_simplest_methods( SPACE "return NULL;\n" "}\n\n", TT, set, set, codegen_rbtree_map__taking_t_argument(op), - codegen_rbtree_map__less(op, vcstr("key"), codegen_rbtree_map__exp_passing_cur_key(op)), - codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), vcstr("key")), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_key_val(op), codegen_rbtree_map__exp_passing_cur_key(op)), + codegen_rbtree_map__less(op, codegen_rbtree_map__exp_passing_cur_key(op), codegen_rbtree_map__exp_passing_key_val(op)), TT, TT, TT, TT, TT, op.v_primitive ? cstr("") : cstr(", .value = value"))); diff --git a/src/l1_5/core/buff_rb_tree_node.h b/src/l1_5/core/buff_rb_tree_node.h index ba9a0db..659c1fd 100644 --- a/src/l1_5/core/buff_rb_tree_node.h +++ b/src/l1_5/core/buff_rb_tree_node.h @@ -3,7 +3,6 @@ #include "../../l1/core/util.h" -// todo: jam that one bit into parent field of BufRBTreeNode typedef enum { RBTree_black = 0, RBTree_red = 1, @@ -220,6 +219,4 @@ void BufRBTree_fix_after_delete(BufRBTreeNode* tree, U64* root, U64 me){ tree[me].color = RBTree_black; } -// todo: move here erase_empty method (renmaed to _erase_empty_by_index) - #endif diff --git a/src/l1_5/core/rb_tree_node.h b/src/l1_5/core/rb_tree_node.h index a311e48..0bc0ec4 100644 --- a/src/l1_5/core/rb_tree_node.h +++ b/src/l1_5/core/rb_tree_node.h @@ -208,7 +208,7 @@ void RBTree_fix_after_delete(RBTreeNode** root, RBTreeNode* NIL, RBTreeNode* me) } else { /* We are on the right */ assert(me == mom->right); RBTreeNode* sister = mom->left; - assert(sister != NULL); + assert(sister != NIL); if (sister->color == RBTREE_RED) { /* Case 1 */ mom->color = RBTREE_RED; sister->color = RBTREE_BLACK; @@ -253,7 +253,7 @@ void RBTree_fix_after_delete(RBTreeNode** root, RBTreeNode* NIL, RBTreeNode* me) void RBTree_erase_empty_by_iter(RBTreeNode** root, RBTreeNode* NIL, RBTreeNode* z) { assert(z != NULL); assert(z != NIL); - RBTreeNode* y = (z->left == NULL || z->right == 0) ? z : RBTreeNode_minimum_in_subtree(z, NIL); + RBTreeNode* y = (z->left == NIL || z->right == NIL) ? z : RBTreeNode_minimum_in_subtree(z->right, NIL); RBTreeNode* x = y->left == NIL ? y->right : y->left; assert(x != y && x != z); RBTreeNode* x_adopter = y->parent; @@ -267,10 +267,10 @@ void RBTree_erase_empty_by_iter(RBTreeNode** root, RBTreeNode* NIL, RBTreeNode* RBTreeClr y_org_clr = y->color; if (z != y) { RBTree_steal_neighbours(root, NIL, z, y); - if (x_adopter == z) - x_adopter = y; + // if (x_adopter == z) + // x_adopter = y; } - x->parent = x_adopter; + // x->parent = x_adopter; if (y_org_clr == RBTREE_BLACK) RBTree_fix_after_delete(root, NIL, x); free((void*)z); diff --git a/src/l2/margaret/vulkan_memory_claire.h b/src/l2/margaret/vulkan_memory_claire.h index 3aa0550..04f4ced 100644 --- a/src/l2/margaret/vulkan_memory_claire.h +++ b/src/l2/margaret/vulkan_memory_claire.h @@ -298,6 +298,7 @@ char* MargaretMemAllocator_get_host_visible_buffer_ptr( #include "../../l1/core/uint_segments.h" #include "../../l1/core/util.h" #include "../../l1_5/core/buff_rb_tree_node.h" +#include "../../l1_5/core/rb_tree_node.h" typedef struct { U64 width; @@ -401,12 +402,6 @@ typedef struct { U32 dev_mem_block; } MargaretFreeMemSegment; -bool MargaretFreeMemSegment_equal( - const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B - ){ - return A->len == B->len && A->dev_mem_block == B->dev_mem_block && A->start == B->start; -} - bool MargaretFreeMemSegment_less( const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B ){ @@ -419,15 +414,6 @@ bool MargaretFreeMemSegment_less( return A->len < B->len; } -bool MargaretFreeMemSegment_equal_resp_align( - const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B, U8 alignment_exp - ){ - U64 A_len = U64Segment_get_length_resp_alignment((U64Segment){A->start, A->len}, alignment_exp); - U64 B_len = U64Segment_get_length_resp_alignment((U64Segment){B->start, B->len}, alignment_exp); - return A_len == B_len && A->dev_mem_block == B->dev_mem_block && A->start == B->start; -} - - bool MargaretFreeMemSegment_less_resp_align( const MargaretFreeMemSegment* A, const MargaretFreeMemSegment* B, U8 alignment_exp ){ diff --git a/src/l2/tests/data_structures/t0.c b/src/l2/tests/data_structures/t0.c index 89dc5ee..d389673 100644 --- a/src/l2/tests/data_structures/t0.c +++ b/src/l2/tests/data_structures/t0.c @@ -1,6 +1,7 @@ -#include "../../../../gen/l1_5/BuffRBTree_SetS64.h" +#include "../../../../gen/l1_5/BufRBTree_SetS64.h" #include "../../../../gen/l1/VecAndSpan_S64.h" #include "../../../l1/core/VecU8_as_str.h" +#include "../../../../gen/l1/OptionS64.h" #include "../../../l1/system/fileio.h" #include "../../../l1/system/fsmanip.h" #include "../../../l1/system/creating_child_proc.h" @@ -25,7 +26,7 @@ U32 check_structure_h_dfs_2(BufRBTreeNode* tree, U64 x){ return a + (tree[x].color == RBTree_black ? 1 : 0); } -S64 min_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){ +S64 min_key_in_subtree(const BufRBTree_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) { @@ -37,7 +38,7 @@ S64 min_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){ return ans; } -S64 max_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){ +S64 max_key_in_subtree(const BufRBTree_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) { @@ -49,7 +50,7 @@ S64 max_key_in_subtree(const BuffRBTree_SetS64* self, U64 x){ return ans; } -void check_only_structure(const BuffRBTree_SetS64* self){ +void check_only_structure(const BufRBTree_SetS64* self){ check(self->tree.len == self->el.len + 1); check(self->root < self->tree.len); if (self->tree.len > 1) { @@ -79,7 +80,7 @@ void check_only_structure(const BuffRBTree_SetS64* self){ } } -void check_correctness(const BuffRBTree_SetS64* self){ +void check_correctness(const BufRBTree_SetS64* self){ check_only_structure(self); /* Checking coloring */ @@ -113,7 +114,7 @@ void check_correctness(const BuffRBTree_SetS64* self){ } } -void save_tree_to_file(const BuffRBTree_SetS64* set, SpanU8 name){ +void save_tree_to_file(const BufRBTree_SetS64* set, SpanU8 name){ check_only_structure(set); VecS64 ranked_node_to_rb_node = VecS64_new_reserved(set->el.len); @@ -194,181 +195,229 @@ void save_tree_to_file(const BuffRBTree_SetS64* set, SpanU8 name){ VecU8_drop(command_nt); } +OptionS64 VecS64_find_max_less(const VecS64* set, S64 key){ + OptionS64 max_less = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] < key) + if (max_less.variant == Option_None || max_less.some < set->buf[i]) + max_less = Some_S64(set->buf[i]); + return max_less; +} + +OptionS64 VecS64_find_max_less_or_eq(const VecS64* set, S64 key){ + OptionS64 max_less = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] <= key) + if (max_less.variant == Option_None || max_less.some < set->buf[i]) + max_less = Some_S64(set->buf[i]); + return max_less; +} + + +OptionS64 VecS64_find_min_grtr(const VecS64* set, S64 key){ + OptionS64 min_grtr = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] > key) + if (min_grtr.variant == Option_None || min_grtr.some > set->buf[i]) + min_grtr = Some_S64(set->buf[i]); + return min_grtr; +} + + +OptionS64 VecS64_find_min_grtr_or_eq(const VecS64* set, S64 key){ + OptionS64 min_grtr = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] >= key) + if (min_grtr.variant == Option_None || min_grtr.some > set->buf[i]) + min_grtr = Some_S64(set->buf[i]); + return min_grtr; +} + +void check_option_int_equiv_node(OptionS64 true_ans, BufRBTree_SetS64* set, U64 my_ans){ + if (true_ans.variant == Option_None) { + check(my_ans == 0); + } else { + check(my_ans != 0 && my_ans < set->tree.len); + check(set->el.buf[my_ans - 1] == true_ans.some); + } +} + + void insert_only(){ { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); check_correctness(&set); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - bool ret = BuffRBTree_SetS64_insert(&set, 42); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + bool ret = BufRBTree_SetS64_insert(&set, 42); check(ret); check_correctness(&set); check(set.el.len == 1); check(set.root == 1); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { bool ret; - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - ret = BuffRBTree_SetS64_insert(&set, 42); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + ret = BufRBTree_SetS64_insert(&set, 42); check(ret); check_correctness(&set); - ret = BuffRBTree_SetS64_insert(&set, 69); + ret = BufRBTree_SetS64_insert(&set, 69); check(ret); check_correctness(&set); check(set.el.len == 2); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { bool ret; - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - ret = BuffRBTree_SetS64_insert(&set, 70); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + ret = BufRBTree_SetS64_insert(&set, 70); check(ret); check_correctness(&set); - ret = BuffRBTree_SetS64_insert(&set, 50); + ret = BufRBTree_SetS64_insert(&set, 50); check(ret); check_correctness(&set); check(set.el.len == 2); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { bool ret; - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - ret = BuffRBTree_SetS64_insert(&set, 1); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + ret = BufRBTree_SetS64_insert(&set, 1); check(ret); check_correctness(&set); - ret = BuffRBTree_SetS64_insert(&set, 2); + ret = BufRBTree_SetS64_insert(&set, 2); check(ret); check_correctness(&set); - ret = BuffRBTree_SetS64_insert(&set, 3); + ret = BufRBTree_SetS64_insert(&set, 3); check(ret); check_correctness(&set); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); for (S64 i = 10; i < 100; i++) { - bool ret = BuffRBTree_SetS64_insert(&set, i); + bool ret = BufRBTree_SetS64_insert(&set, i); check(ret); check_correctness(&set); } - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); for (S64 i = 99; i >= 10; i--) { - bool ret = BuffRBTree_SetS64_insert(&set, i); + bool ret = BufRBTree_SetS64_insert(&set, i); check(ret); check_correctness(&set); } - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); for (S64 i = 10; i < 100; i++) { - bool ret = BuffRBTree_SetS64_insert(&set, i); + bool ret = BufRBTree_SetS64_insert(&set, i); check(ret); check_correctness(&set); - bool ret2 = BuffRBTree_SetS64_insert(&set, 1000 - i); + bool ret2 = BufRBTree_SetS64_insert(&set, 1000 - i); check(ret2); check_correctness(&set); } - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - // BuffRBTree_SetS64_erase_substitute() - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + // BufRBTree_SetS64_erase_substitute() + BufRBTree_SetS64_drop(set); } } void insert_and_then_find(){ - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); for (S64 p = 0; p < 100; p++) { - bool ret = BuffRBTree_SetS64_insert(&set, 2 * p); + bool ret = BufRBTree_SetS64_insert(&set, 2 * p); check(ret); check_correctness(&set); for (S64 i = 0; i <= p; i++) { - U64 ret1 = BuffRBTree_SetS64_find(&set, 2 * i); + U64 ret1 = BufRBTree_SetS64_find(&set, 2 * i); check(ret1); - U64 ret2 = BuffRBTree_SetS64_find(&set, 2 * i + 1); + U64 ret2 = BufRBTree_SetS64_find(&set, 2 * i + 1); check(ret2 == 0); } } - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } void insert_and_delete(){ { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - check(BuffRBTree_SetS64_insert(&set, 1)) + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + check(BufRBTree_SetS64_insert(&set, 1)) check_correctness(&set); - check(BuffRBTree_SetS64_find(&set, 1)); - check(BuffRBTree_SetS64_erase(&set, 1)); + check(BufRBTree_SetS64_find(&set, 1)); + check(BufRBTree_SetS64_erase(&set, 1)); check_correctness(&set); - check(!BuffRBTree_SetS64_find(&set, 1)); - BuffRBTree_SetS64_drop(set); + check(!BufRBTree_SetS64_find(&set, 1)); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - check(BuffRBTree_SetS64_insert(&set, 1)) + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + check(BufRBTree_SetS64_insert(&set, 1)) check_correctness(&set); - check(BuffRBTree_SetS64_insert(&set, 2)) + check(BufRBTree_SetS64_insert(&set, 2)) check_correctness(&set); - check(BuffRBTree_SetS64_erase(&set, 2)); + check(BufRBTree_SetS64_erase(&set, 2)); check_correctness(&set); - check(BuffRBTree_SetS64_find(&set, 1)); - check(!BuffRBTree_SetS64_find(&set, 2)); - check(BuffRBTree_SetS64_erase(&set, 1)); + check(BufRBTree_SetS64_find(&set, 1)); + check(!BufRBTree_SetS64_find(&set, 2)); + check(BufRBTree_SetS64_erase(&set, 1)); check_correctness(&set); - check(!BuffRBTree_SetS64_find(&set, 1)); - check(!BuffRBTree_SetS64_find(&set, 2)); - BuffRBTree_SetS64_drop(set); + check(!BufRBTree_SetS64_find(&set, 1)); + check(!BufRBTree_SetS64_find(&set, 2)); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - check(BuffRBTree_SetS64_insert(&set, 1)) + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + check(BufRBTree_SetS64_insert(&set, 1)) check_correctness(&set); - check(BuffRBTree_SetS64_insert(&set, 2)) + check(BufRBTree_SetS64_insert(&set, 2)) check_correctness(&set); - check(BuffRBTree_SetS64_erase(&set, 1)); + check(BufRBTree_SetS64_erase(&set, 1)); check_correctness(&set); - check(!BuffRBTree_SetS64_find(&set, 1)); - check(BuffRBTree_SetS64_find(&set, 2)); + check(!BufRBTree_SetS64_find(&set, 1)); + check(BufRBTree_SetS64_find(&set, 2)); - check(!BuffRBTree_SetS64_erase(&set, 1)); - check(!BuffRBTree_SetS64_find(&set, 1)); - check(BuffRBTree_SetS64_find(&set, 2)); - check(BuffRBTree_SetS64_erase(&set, 2)); + check(!BufRBTree_SetS64_erase(&set, 1)); + check(!BufRBTree_SetS64_find(&set, 1)); + check(BufRBTree_SetS64_find(&set, 2)); + check(BufRBTree_SetS64_erase(&set, 2)); check_correctness(&set); - check(!BuffRBTree_SetS64_find(&set, 1)); - check(!BuffRBTree_SetS64_find(&set, 2)); - BuffRBTree_SetS64_drop(set); + check(!BufRBTree_SetS64_find(&set, 1)); + check(!BufRBTree_SetS64_find(&set, 2)); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); for (S64 i = -120; i < 1000; i += 10) { - check(BuffRBTree_SetS64_insert(&set, i)) + check(BufRBTree_SetS64_insert(&set, i)) check_correctness(&set); } // save_tree_to_file(&set, cstr("tree")); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } { - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); - check(BuffRBTree_SetS64_insert(&set, 1)) + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); + check(BufRBTree_SetS64_insert(&set, 1)) check_correctness(&set); - check(BuffRBTree_SetS64_insert(&set, 2)) + check(BufRBTree_SetS64_insert(&set, 2)) check_correctness(&set); - check(BuffRBTree_SetS64_insert(&set, 3)) + check(BufRBTree_SetS64_insert(&set, 3)) check_correctness(&set); // save_tree_to_file(&set, cstr("trio")); - check(BuffRBTree_SetS64_erase(&set, 2)); + check(BufRBTree_SetS64_erase(&set, 2)); check_correctness(&set); // save_tree_to_file(&set, cstr("duo")); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } } @@ -396,29 +445,29 @@ VecS64 gen_cool_sequence(S64 i){ void chaos(){ for (int i = 1; i < 100; i++) { srand(i); - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_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); + BufRBTree_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)); + check(BufRBTree_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); + BufRBTree_SetS64_drop(set); } } void triple_black(){ - BuffRBTree_SetS64 set; + BufRBTree_SetS64 set; { VecBufRBTreeNode tree = VecBufRBTreeNode_new_zeroinit(4); tree.buf[1] = (BufRBTreeNode){.parent = 3}; @@ -428,22 +477,22 @@ void triple_black(){ VecS64_append(&el, 300); VecS64_append(&el, 100); VecS64_append(&el, 200); - set = (BuffRBTree_SetS64){.tree = tree, .root = 3, .el = el}; + set = (BufRBTree_SetS64){.tree = tree, .root = 3, .el = el}; } check_correctness(&set); - check(BuffRBTree_SetS64_erase(&set, 300)); + check(BufRBTree_SetS64_erase(&set, 300)); check_correctness(&set); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); } void absolute_chaos(){ for (int i = 1; i < 100; i++) { srand(i); - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_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(BufRBTree_SetS64_insert(&set, to_insert)); check_correctness(&set); } printf("Filled chaos with i = %d\n", i); @@ -452,14 +501,14 @@ void absolute_chaos(){ 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(BufRBTree_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); + BufRBTree_SetS64_drop(set); } } @@ -467,7 +516,7 @@ void stress(){ printf("Prepare for some real stress\n"); for (int s = 2; s < 1000; s++) { srand(s); - BuffRBTree_SetS64 set = BuffRBTree_SetS64_new(); + BufRBTree_SetS64 set = BufRBTree_SetS64_new(); VecS64 real_set = VecS64_new(); U32 n = (U32)s; VecS64 complementary_set = VecS64_new_reserved(n); @@ -476,7 +525,7 @@ void stress(){ } for (int t = 0; t < 1000; t++) { /* Do something */ - int do_insertion = rand() % 2; + bool do_insertion = (rand() % 9) >= 4; if (real_set.len == 0) do_insertion = 1; if (complementary_set.len == 0) @@ -486,28 +535,52 @@ void stress(){ 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)); + check(BufRBTree_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(BufRBTree_SetS64_erase(&set, v)); check_correctness(&set); } /* 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); + check(BufRBTree_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); + check(BufRBTree_SetS64_find(&set, complementary_set.buf[j]) == 0); + } + /* Checking weird methods that nobody needs */ + for (int tt = 0; tt < 15; tt++) { + S64 key = (S64)(rand() % n) * 10; + { + OptionS64 true_ans = VecS64_find_max_less(&real_set, key); + U64 my_ans = BufRBTree_SetS64_find_max_less(&set, key); + check_option_int_equiv_node(true_ans, &set, my_ans); + } + { + OptionS64 true_ans = VecS64_find_max_less_or_eq(&real_set, key); + U64 my_ans = BufRBTree_SetS64_find_max_less_or_eq(&set, key); + check_option_int_equiv_node(true_ans, &set, my_ans); + } + { + OptionS64 true_ans = VecS64_find_min_grtr(&real_set, key); + U64 my_ans = BufRBTree_SetS64_find_min_grtr(&set, key); + check_option_int_equiv_node(true_ans, &set, my_ans); + } + { + OptionS64 true_ans = VecS64_find_min_grtr_or_eq(&real_set, key); + U64 my_ans = BufRBTree_SetS64_find_min_grtr_or_eq(&set, key); + check_option_int_equiv_node(true_ans, &set, my_ans); + } } } VecS64_drop(real_set); VecS64_drop(complementary_set); - BuffRBTree_SetS64_drop(set); + BufRBTree_SetS64_drop(set); printf("Seed s=%d passed test\n", s); } } diff --git a/src/l2/tests/data_structures/t0_2.c b/src/l2/tests/data_structures/t0_2.c index 5734c30..7a71f1b 100644 --- a/src/l2/tests/data_structures/t0_2.c +++ b/src/l2/tests/data_structures/t0_2.c @@ -1,381 +1,381 @@ // todo: rewrite this test with structures from l1_5/eve/margaret // todo: but before that: don't even bother running this test -#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; -} +// #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; +// } diff --git a/src/l2/tests/data_structures/t0_3.c b/src/l2/tests/data_structures/t0_3.c index 95e0f19..a249e13 100644 --- a/src/l2/tests/data_structures/t0_3.c +++ b/src/l2/tests/data_structures/t0_3.c @@ -1,6 +1,7 @@ #include "../../../../gen/l1_5/RBTree_SetS64.h" #include "../../../../gen/l1/VecAndSpan_U8.h" #include "../../../../gen/l1/VecAndSpan_S64.h" +#include "../../../../gen/l1/OptionS64.h" #include "../../../l1/core/VecU8_as_str.h" #include "../../../l1/system/fileio.h" @@ -79,8 +80,10 @@ void save_tree_to_file(const RBTree_SetS64* set, SpanU8 name){ VecRefRBTreeNode_S64 bfs_nxt = VecRefRBTreeNode_S64_new(); VecRefRBTreeNode_S64 bfs = VecRefRBTreeNode_S64_new(); - if (set->root != set->NIL) + if (set->root != set->NIL) { + check(set->root->parent == set->NIL); VecRefRBTreeNode_S64_append(&bfs_nxt, (RBTreeNode_S64*)set->root); + } while (bfs_nxt.len > 0) { VecRefRBTreeNode_S64 t = bfs_nxt; bfs_nxt = bfs; @@ -88,10 +91,15 @@ void save_tree_to_file(const RBTree_SetS64* set, SpanU8 name){ for (size_t j = 0; j < bfs.len; j++) { RBTreeNode_S64* cur = *VecRefRBTreeNode_S64_at(&bfs, j); assert(cur != NULL); - if (cur->base.left != set->NIL) + if (cur->base.left != set->NIL) { + check(cur->base.left->parent == &cur->base); VecRefRBTreeNode_S64_append(&bfs, (RBTreeNode_S64*)cur->base.left); - if (cur->base.right != set->NIL) + } + + if (cur->base.right != set->NIL) { + check(cur->base.right->parent == &cur->base); VecRefRBTreeNode_S64_append(&bfs, (RBTreeNode_S64*)cur->base.right); + } VecU8_append_vec(&graph, VecU8_fmt( " v%i [label=%i, color=%s, fontcolor=%s]\n", @@ -179,6 +187,7 @@ void insert_only(){ } } RBTree_SetS64_drop(set); + VecS64_drop(have); } } @@ -198,15 +207,63 @@ void s_4_t_42(){ .base.color = RBTREE_BLACK, .key = 30}; RBTree_SetS64 set = {.root = &v20->base, .NIL = NIL}; check_correctness(&set); - save_tree_to_file(&set, cstr("SOROK_ONE")); + // save_tree_to_file(&set, cstr("SOROK_ONE")); check(RBTree_SetS64_erase(&set, 20)); - save_tree_to_file(&set, cstr("I_AM_LOOSING_MY_FUCKING_MIND")); + // save_tree_to_file(&set, cstr("I_AM_LOOSING_MY_MIND")); check_correctness(&set); + RBTree_SetS64_drop(set); } +OptionS64 VecS64_find_max_less(const VecS64* set, S64 key){ + OptionS64 max_less = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] < key) + if (max_less.variant == Option_None || max_less.some < set->buf[i]) + max_less = Some_S64(set->buf[i]); + return max_less; +} + +OptionS64 VecS64_find_max_less_or_eq(const VecS64* set, S64 key){ + OptionS64 max_less = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] <= key) + if (max_less.variant == Option_None || max_less.some < set->buf[i]) + max_less = Some_S64(set->buf[i]); + return max_less; +} + + +OptionS64 VecS64_find_min_grtr(const VecS64* set, S64 key){ + OptionS64 min_grtr = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] > key) + if (min_grtr.variant == Option_None || min_grtr.some > set->buf[i]) + min_grtr = Some_S64(set->buf[i]); + return min_grtr; +} + + +OptionS64 VecS64_find_min_grtr_or_eq(const VecS64* set, S64 key){ + OptionS64 min_grtr = None_S64(); + for (size_t i = 0; i < set->len; i++) + if (set->buf[i] >= key) + if (min_grtr.variant == Option_None || min_grtr.some > set->buf[i]) + min_grtr = Some_S64(set->buf[i]); + return min_grtr; +} + +void check_option_int_equiv_node(OptionS64 true_ans, RBTreeNode_S64* my_ans){ + if (true_ans.variant == Option_None) { + check(my_ans == NULL); + } else { + check(my_ans != NULL && my_ans->key == true_ans.some); + } +} + + void stress(){ printf("Are you ready for real stress?\n"); - for (int s = 4; s < 1000; s++) { + for (int s = 2; s < 1000; s++) { srand(s); RBTree_SetS64 set = RBTree_SetS64_new(); VecS64 real_set = VecS64_new(); @@ -217,7 +274,7 @@ void stress(){ } for (int t = 0; t < 1000; t++) { /* Do something */ - int do_insertion = rand() % 2; + bool do_insertion = (rand() % 9) >= 4; if (real_set.len == 0) do_insertion = 1; if (complementary_set.len == 0) @@ -246,6 +303,49 @@ void stress(){ for (size_t j = 0; j < complementary_set.len; j++) { check(RBTree_SetS64_find(&set, complementary_set.buf[j]) == NULL); } + + { /* Tree detour forward */ + U64 count = 0; + RBTreeNode_S64* cur = RBTree_SetS64_find_min(&set); + while (cur) { + count++; + cur = RBTree_SetS64_find_next(&set, cur); + } + check(count == real_set.len); + } + { /* Tree detour backward */ + U64 count = 0; + RBTreeNode_S64* cur = RBTree_SetS64_find_max(&set); + while (cur) { + count++; + cur = RBTree_SetS64_find_prev(&set, cur); + } + check(count == real_set.len); + } + /* Checking weird methods that nobody needs */ + for (int tt = 0; tt < 15; tt++) { + S64 key = (S64)(rand() % n) * 10; + { + OptionS64 true_ans = VecS64_find_max_less(&real_set, key); + RBTreeNode_S64* my_ans = RBTree_SetS64_find_max_less(&set, key); + check_option_int_equiv_node(true_ans, my_ans); + } + { + OptionS64 true_ans = VecS64_find_max_less_or_eq(&real_set, key); + RBTreeNode_S64* my_ans = RBTree_SetS64_find_max_less_or_eq(&set, key); + check_option_int_equiv_node(true_ans, my_ans); + } + { + OptionS64 true_ans = VecS64_find_min_grtr(&real_set, key); + RBTreeNode_S64* my_ans = RBTree_SetS64_find_min_grtr(&set, key); + check_option_int_equiv_node(true_ans, my_ans); + } + { + OptionS64 true_ans = VecS64_find_min_grtr_or_eq(&real_set, key); + RBTreeNode_S64* my_ans = RBTree_SetS64_find_min_grtr_or_eq(&set, key); + check_option_int_equiv_node(true_ans, my_ans); + } + } } VecS64_drop(real_set); VecS64_drop(complementary_set); @@ -255,8 +355,8 @@ void stress(){ } int main(){ - // insert_only(); - // stress(); + insert_only(); + stress(); s_4_t_42(); return 0; }