diff --git a/src/utils/ufd.c b/src/utils/ufd.c new file mode 100644 index 0000000..98e115b --- /dev/null +++ b/src/utils/ufd.c @@ -0,0 +1,61 @@ +#include "ufd.h" +#include "stdlib.h" +#include + +struct ufd_t ufd__make_set(struct context_entry_t* thread) +{ + struct ufd_children_t children = TAILQ_HEAD_INITIALIZER(children); + + return (struct ufd_t) { + .thread = thread, + .parent = NULL, + .repr = NULL, + .children = children, + }; +} + + +void ufd__init(struct ufd_t* ufd, struct context_entry_t* thread) +{ + TAILQ_INIT(&ufd->children); + ufd->thread = thread; + ufd->repr = NULL, + ufd->parent = NULL; +} + + +void ufd__join(struct ufd_t* th1, struct ufd_t* th2) +{ + struct ufd_t* a = ufd__find(th1); + struct ufd_t* b = ufd__find(th2); + + if (a != b) + { + a->parent = b; + a->repr = b; + } +} + + +struct ufd_t* ufd__find(struct ufd_t* th) +{ + if (th->parent == NULL) + return th; + + // If parent is null, repr can't be null + if (th->repr->parent == NULL) + return th->repr; + + struct ufd_t* nrepr = ufd__find(th->repr); + th->repr = nrepr; + return nrepr; +} + + +void ufd__delete(struct ufd_t* th) +{ + struct ufd_t* child; + TAILQ_FOREACH(child, &th->children, link) { + child->parent = NULL; + } +} diff --git a/src/utils/ufd.h b/src/utils/ufd.h new file mode 100644 index 0000000..9ba2d38 --- /dev/null +++ b/src/utils/ufd.h @@ -0,0 +1,35 @@ +#ifndef _UNION_FIND_H_ +#define _UNION_FIND_H_ +#include + +TAILQ_HEAD(ufd_children_t, ufd_t); + +// union find delete data structure +struct ufd_t { + struct ufd_t* parent; + struct ufd_t* repr; + struct context_entry_t* thread; + struct ufd_children_t children; + TAILQ_ENTRY(ufd_t) link; +}; + + +struct ufd_t ufd__make_set(struct context_entry_t* thread); + +void ufd__init(struct ufd_t* ufd, struct context_entry_t* thread); + +/* + * Join th1 set to th2 set + */ +void ufd__join(struct ufd_t* th1, struct ufd_t* th2); + +/* + * Find th's representent + */ +struct ufd_t* ufd__find(struct ufd_t* th); + +/* + * Deletes th from its set + */ +void ufd__delete(struct ufd_t* th); +#endif // _UNION_FIND_H_