Almost wrote RBTree, almost refactored RBTree. Minor methods missing. All tests passed. Method _equal_ is no longer requires for set/map instantiation
This commit is contained in:
parent
704930efcc
commit
4cd6e65ea9
@ -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)
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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")));
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
){
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
// }
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user