72 lines
1.8 KiB
C
72 lines
1.8 KiB
C
|
/* 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;
|
||
|
}
|