libcdsb/src/set/compute.c

72 lines
1.8 KiB
C
Raw Normal View History

2022-08-19 17:19:22 +03:00
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "../../include/set.h"
#include "../__internal/rbtree.h"
static inline hash_t rbnode_hash(const rbnode_t* s, vtype t) {
return vnode_hash(&s->value, t);
}
/*#####################################################################################################################*/
size_t vset_size(const set_t* x) {
stack_t z;
size_t n;
rbnode_t* c;
stack_init(&z);
stack_push(&z, x->root);
n = 0;
if (!rbnode_is_empty(x->root)) {
while ((c = stack_pop(&z))) {
++n;
if (!rbnode_is_empty(c->right)) stack_push(&z, c->right);
if (!rbnode_is_empty(c->left)) stack_push(&z, c->left);
}
}
return n;
}
hash_t vset_hash(const set_t* s) {
stack_t z;
rbnode_t *c0, *c1;
hash_t hash, v;
if (rbnode_is_empty(s->root))
return 0;
stack_init(&z);
stack_push(&z, s->root->left);
hash = 1;
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
do {
++hash;
if (!rbnode_is_empty(c0->right)) stack_push(&z, c0->right);
if (!rbnode_is_empty(c0->left)) stack_push(&z, c1 = c0->left);
} while (!is_null(c0 = stack_pop(&z)));
}
v = rbnode_hash(c1, s->type);
stack_push(&z, s->root->right);
if (!rbnode_is_empty(c0 = stack_pop(&z))) {
do {
++hash;
if (!rbnode_is_empty(c0->right)) stack_push(&z, c1 = c0->right);
if (!rbnode_is_empty(c0->left)) stack_push(&z, c0->left);
} while (!is_null(c0 = stack_pop(&z)));
}
v += rbnode_hash(c1, s->type);
return (hash ^ v) + VTYPE_SET;
}