2022-06-02 22:23:01 +03:00
|
|
|
/* This software is licensed by the MIT License, see LICENSE file */
|
|
|
|
/* Copyright © 2022 Gregory Lirent */
|
|
|
|
|
2022-06-08 10:52:29 +03:00
|
|
|
#include "../../../src/map/include.h"
|
2022-06-02 22:23:01 +03:00
|
|
|
|
|
|
|
#include "../../include/random.h"
|
|
|
|
#include "../../include/test.h"
|
|
|
|
#include "../../include/time.h"
|
|
|
|
|
|
|
|
vtype_string* string_duplicate(const vtype_string* x) { return 0; }
|
|
|
|
vtype_array* array_duplicate (const vtype_array* x) { return 0; }
|
|
|
|
vtype_list* list_duplicate (const vtype_list* x) { return 0; }
|
|
|
|
vtype_set* vset_duplicate (const vtype_set* x) { return 0; }
|
|
|
|
|
|
|
|
void string_free(vtype_string* x) {}
|
|
|
|
void array_free (vtype_array* x) {}
|
|
|
|
void list_free (vtype_list* x) {}
|
|
|
|
void vset_free (vtype_set* x) {}
|
|
|
|
|
|
|
|
int string_compare(const vtype_string* s0, const vtype_string* s1) { return random_int8(); }
|
|
|
|
int array_compare (const vtype_array* s0, const vtype_array* s1) { return random_int8(); }
|
|
|
|
int list_compare (const vtype_list* s0, const vtype_list* s1) { return random_int8(); }
|
|
|
|
int vset_compare (const vtype_set* s0, const vtype_set* s1) { return random_int8(); }
|
2022-06-08 10:52:29 +03:00
|
|
|
|
|
|
|
|
|
|
|
static int map_node_print(const void* k, vtype kt, void* v, vtype vt, void* _) {
|
|
|
|
printf(" \e[31m%24s\e[m \e[36m:\e[m", vtype_stringify(k, kt));
|
|
|
|
printf(" \e[31m%s\e[m", vtype_stringify(v, vt));
|
|
|
|
printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m\n", vtype_name(vt));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void map_print(map_t* x, const char* prefix) {
|
|
|
|
print_container_values_prefix("Map", prefix);
|
|
|
|
map_foreach(x, 0, map_node_print);
|
|
|
|
put_separator();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void map_info(const map_t* x) {
|
|
|
|
print_container_info("Map", "nodes", &x->type, map_size(x), -1);
|
|
|
|
put_separator();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void map_rbtree_print(const mnode_t* s, vtype t, const char* ind, bool br) {
|
|
|
|
if (!ind) {
|
|
|
|
ind = "\e[36m";
|
|
|
|
br = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t n = strlen(ind);
|
|
|
|
char x[n + 10];
|
|
|
|
|
|
|
|
if (mnode_is_empty(s)) return;
|
|
|
|
|
|
|
|
memcpy(x, ind, n);
|
|
|
|
memcpy(x + n, " \0 ", 9);
|
|
|
|
fputs(ind, stdout);
|
|
|
|
|
|
|
|
if (br) {
|
|
|
|
fputs("\e[m\e[36;1mR\e[m\e[36m────\e[m", stdout);
|
|
|
|
} else {
|
|
|
|
fputs("\e[m\e[36;1mL\e[m\e[36m────\e[m", stdout);
|
|
|
|
memcpy(x + n, "│", 3);
|
|
|
|
x[n + 5] = ' ';
|
|
|
|
}
|
|
|
|
|
|
|
|
fputs((s->colored) ? "\e[31;1m" : "\e[37m", stdout);
|
|
|
|
printf("%s\e[m \e[36m:\e[m ", vnode_stringify(&s->key, t));
|
|
|
|
printf("\e[31m%s\e[m", vnode_stringify(&s->value, s->type));
|
|
|
|
printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m\n", vtype_name(s->type));
|
|
|
|
|
|
|
|
map_rbtree_print(s->left, t, x, false);
|
|
|
|
map_rbtree_print(s->right, t, x, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void map_push_random(map_t* x, double pause) {
|
|
|
|
var_t _[2];
|
|
|
|
vtype t[2];
|
|
|
|
|
|
|
|
printf("\e[s\e[36mUpdate value in map (\e[m\e[32;1m%s\e[m\e[36m)\e[m:\n", vtype_name(x->type));
|
|
|
|
|
|
|
|
switch (random_uint8()%13) {
|
|
|
|
default:
|
|
|
|
case 0: _[0].b = random_boolean(); print_container_value(0, _, t[0] = VTYPE_BOOLEAN, 1); break;
|
|
|
|
case 1: _[0].u8 = random_uint8(); print_container_value(0, _, t[0] = VTYPE_UINT8, 1); break;
|
|
|
|
case 2: _[0].u16 = random_uint16(); print_container_value(0, _, t[0] = VTYPE_UINT16, 1); break;
|
|
|
|
case 3: _[0].u32 = random_uint32(); print_container_value(0, _, t[0] = VTYPE_UINT32, 1); break;
|
|
|
|
case 4: _[0].u64 = random_uint64(); print_container_value(0, _, t[0] = VTYPE_UINT64, 1); break;
|
|
|
|
case 5: _[0].u8 = random_int8(); print_container_value(0, _, t[0] = VTYPE_INT8, 1); break;
|
|
|
|
case 6: _[0].u16 = random_int16(); print_container_value(0, _, t[0] = VTYPE_INT16, 1); break;
|
|
|
|
case 7: _[0].u32 = random_int32(); print_container_value(0, _, t[0] = VTYPE_INT32, 1); break;
|
|
|
|
case 8: _[0].u64 = random_int64(); print_container_value(0, _, t[0] = VTYPE_INT64, 1); break;
|
|
|
|
case 9: _[0].f = random_float(); print_container_value(0, _, t[0] = VTYPE_FLOAT, 1); break;
|
|
|
|
case 10: _[0].d = random_double(); print_container_value(0, _, t[0] = VTYPE_DOUBLE, 1); break;
|
|
|
|
case 11: _[0].ld = random_ldouble(); print_container_value(0, _, t[0] = VTYPE_LDOUBLE, 1); break;
|
|
|
|
|
|
|
|
case 12: if (sizeof(void*) == 8) {
|
|
|
|
_[0].u64 = random_uint64(); print_container_value(0, _, t[0] = VTYPE_POINTER, 1); break;
|
|
|
|
} else {
|
|
|
|
_[0].u32 = random_uint32(); print_container_value(0, _, t[0] = VTYPE_POINTER, 1); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (random_uint8()%13) {
|
|
|
|
default:
|
|
|
|
case 0: _[1].b = random_boolean(); print_container_value(0, _+1, t[1] = VTYPE_BOOLEAN, 1); break;
|
|
|
|
case 1: _[1].u8 = random_uint8(); print_container_value(0, _+1, t[1] = VTYPE_UINT8, 1); break;
|
|
|
|
case 2: _[1].u16 = random_uint16(); print_container_value(0, _+1, t[1] = VTYPE_UINT16, 1); break;
|
|
|
|
case 3: _[1].u32 = random_uint32(); print_container_value(0, _+1, t[1] = VTYPE_UINT32, 1); break;
|
|
|
|
case 4: _[1].u64 = random_uint64(); print_container_value(0, _+1, t[1] = VTYPE_UINT64, 1); break;
|
|
|
|
case 5: _[1].u8 = random_int8(); print_container_value(0, _+1, t[1] = VTYPE_INT8, 1); break;
|
|
|
|
case 6: _[1].u16 = random_int16(); print_container_value(0, _+1, t[1] = VTYPE_INT16, 1); break;
|
|
|
|
case 7: _[1].u32 = random_int32(); print_container_value(0, _+1, t[1] = VTYPE_INT32, 1); break;
|
|
|
|
case 8: _[1].u64 = random_int64(); print_container_value(0, _+1, t[1] = VTYPE_INT64, 1); break;
|
|
|
|
case 9: _[1].f = random_float(); print_container_value(0, _+1, t[1] = VTYPE_FLOAT, 1); break;
|
|
|
|
case 10: _[1].d = random_double(); print_container_value(0, _+1, t[1] = VTYPE_DOUBLE, 1); break;
|
|
|
|
case 11: _[1].ld = random_ldouble(); print_container_value(0, _+1, t[1] = VTYPE_LDOUBLE, 1); break;
|
|
|
|
|
|
|
|
case 12: if (sizeof(void*) == 8) {
|
|
|
|
_[1].u64 = random_uint64(); print_container_value(0, _+1, t[1] = VTYPE_POINTER, 1); break;
|
|
|
|
} else {
|
|
|
|
_[1].u32 = random_uint32(); print_container_value(0, _+1, t[1] = VTYPE_POINTER, 1); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (libcdsb_map_update(x, _, t[0], _+1, t[1])) {
|
|
|
|
puts("\e[33;1mCHANGE\e[m");
|
|
|
|
} else {
|
|
|
|
puts("\e[32;1mINSERT\e[m");
|
|
|
|
}
|
|
|
|
|
|
|
|
put_separator();
|
|
|
|
|
|
|
|
map_rbtree_print(x->root, x->type, 0, 0);
|
|
|
|
put_separator();
|
|
|
|
psleep(pause * 1000000);
|
|
|
|
fputs("\e[u\e[J", stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int map_node_remove_random(const void* k, vtype kt, void* v, vtype vt, void* data) {
|
|
|
|
struct {
|
|
|
|
size_t n;
|
|
|
|
map_t* set;
|
|
|
|
double pause;
|
|
|
|
} *d = data;
|
|
|
|
|
|
|
|
if (!d->n--) {
|
|
|
|
map_node_print(k, kt, v, vt, 0);
|
|
|
|
|
|
|
|
if (libcdsb_map_find(0, d->set, k, kt, 1)) {
|
|
|
|
puts("\e[32;1mSUCCESS\e[m");
|
|
|
|
} else {
|
|
|
|
puts("\e[s\e[31;1mFAILURE\e[m");
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
put_separator();
|
|
|
|
|
|
|
|
map_rbtree_print(d->set->root, d->set->type, 0, 0);
|
|
|
|
put_separator();
|
|
|
|
psleep(d->pause * 1000000);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool map_remove_random(map_t* x, double pause) {
|
|
|
|
struct {
|
|
|
|
size_t n;
|
|
|
|
map_t* set;
|
|
|
|
double pause;
|
|
|
|
} d;
|
|
|
|
d.n = map_size(x);
|
|
|
|
d.set = x;
|
|
|
|
d.pause = pause;
|
|
|
|
|
|
|
|
printf("\e[s\e[36mTry to remove value from map (\e[m\e[32;1m%s\e[m\e[36m)\e[m:\n", libcdsb_vtype_name(x->type));
|
|
|
|
|
|
|
|
if (d.n) {
|
|
|
|
d.n = random_uint32()%d.n;
|
|
|
|
} else goto end_;
|
|
|
|
|
|
|
|
if (!map_foreach(x, &d, map_node_remove_random)) {
|
|
|
|
end_:
|
|
|
|
puts("\e[u\e[J\e[32;1mMap is empty\e[m");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fputs("\e[u\e[J", stdout);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static map_t map_random(unsigned int n, double pause) {
|
|
|
|
map_t x;
|
|
|
|
|
|
|
|
switch (random_uint8()%12) {
|
|
|
|
default:
|
|
|
|
case 0: map_init(&x, VTYPE_UINT8); break;
|
|
|
|
case 1: map_init(&x, VTYPE_UINT16); break;
|
|
|
|
case 2: map_init(&x, VTYPE_UINT32); break;
|
|
|
|
case 3: map_init(&x, VTYPE_UINT64); break;
|
|
|
|
case 4: map_init(&x, VTYPE_INT8); break;
|
|
|
|
case 5: map_init(&x, VTYPE_INT16); break;
|
|
|
|
case 6: map_init(&x, VTYPE_INT32); break;
|
|
|
|
case 7: map_init(&x, VTYPE_INT64); break;
|
|
|
|
case 8: map_init(&x, VTYPE_POINTER); break;
|
|
|
|
case 9: map_init(&x, VTYPE_FLOAT); break;
|
|
|
|
case 10: map_init(&x, VTYPE_DOUBLE); break;
|
|
|
|
case 11: map_init(&x, VTYPE_LDOUBLE); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n) {
|
|
|
|
while (--n) map_push_random(&x, pause);
|
|
|
|
map_push_random(&x, pause);
|
|
|
|
}
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|