/* 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; }