24 #ifndef GRAPHLAB_UTIL_UNION_FIND_HPP
25 #define GRAPHLAB_UTIL_UNION_FIND_HPP
28 #include <graphlab/parallel/atomic.hpp>
33 template <
typename IDType,
typename RankType>
36 std::vector<std::pair<IDType, RankType> > setid;
38 bool is_root(IDType i) {
39 return setid[i].first == (IDType)i;
45 setid.resize((
size_t)s);
46 for (
size_t i = 0; i < setid.size() ;++i) {
47 setid[i].first = (IDType)(i);
52 void merge(IDType i, IDType j) {
53 IDType iroot = find(i);
54 IDType jroot = find(j);
55 if (iroot == jroot)
return;
56 else if (setid[iroot].second < setid[jroot].second) {
57 setid[iroot].first = jroot;
59 else if (setid[iroot].second > setid[jroot].second) {
60 setid[jroot].first = iroot;
63 setid[jroot].first = iroot;
65 if (setid[iroot].second + 1 > setid[iroot].second) {
66 setid[iroot].second = setid[iroot].second + 1;
71 IDType find(IDType i) {
73 if (is_root(root))
return root;
76 while (!is_root(root)) { root = setid[root].first; }
80 while (!is_root(cur)) {
81 IDType parent = setid[cur].first;
82 setid[cur].first = root;
86 return setid[i].first;
91 class concurrent_union_find {
101 std::vector<elem> setid;
103 bool is_root(uint32_t i) {
104 return setid[i].d.next == i;
107 bool updateroot(uint32_t x, uint32_t oldrank,
108 uint32_t y, uint32_t newrank) {
109 elem old; old.d.next = x; old.d.rank = oldrank;
110 elem newval; newval.d.next = y; newval.d.rank = newrank;
115 concurrent_union_find() { }
116 void init(uint32_t s) {
117 setid.resize((
size_t)s);
118 for (
size_t i = 0; i < setid.size() ;++i) {
119 setid[i].d.next = (uint32_t)(i);
124 void merge(uint32_t x, uint32_t y) {
131 xr = setid[x].d.rank;
132 yr = setid[y].d.rank;
134 if (xr > yr || (xr == yr && x > y)) {
135 std::swap(x,y); std::swap(xr, yr);
138 if (updateroot(x, xr, y, xr))
break;
141 __sync_add_and_fetch(&(setid[y].d.rank), 1);
145 uint32_t find(uint32_t x) {
146 if (is_root(x))
return x;
150 while (!is_root(x)) { x = setid[x].d.next; }
153 while (setid[y].d.rank < setid[x].d.rank) {
154 uint32_t t = setid[y].d.next;