00001
00026 #ifndef GALOIS_UNIONFIND_H
00027 #define GALOIS_UNIONFIND_H
00028
00029 namespace Galois {
00034 template<typename T>
00035 class UnionFindNode {
00036 T* findImpl() const {
00037 if (isRep()) return m_component;
00038
00039 T* rep = m_component;
00040 while (rep->m_component != rep) {
00041 T* next = rep->m_component;
00042 rep = next;
00043 }
00044 return rep;
00045 }
00046
00047 protected:
00048 T* m_component;
00049
00050 UnionFindNode(): m_component(reinterpret_cast<T*>(this)) { }
00051
00052 public:
00053 typedef UnionFindNode<T> SuperTy;
00054
00055 bool isRep() const {
00056 return m_component == this;
00057 }
00058
00059 const T* find() const { return findImpl(); }
00060
00061 T* find() { return findImpl(); }
00062
00063 T* findAndCompress() {
00064
00065
00066
00067
00068 if (isRep()) return m_component;
00069
00070 T* rep = m_component;
00071 T* prev = 0;
00072 while (rep->m_component != rep) {
00073 T* next = rep->m_component;
00074
00075 if (prev && prev->m_component == rep) {
00076 prev->m_component = next;
00077 }
00078 prev = rep;
00079 rep = next;
00080 }
00081 return rep;
00082 }
00083
00085 T* merge(T* b) {
00086 T* a = m_component;
00087 while (true) {
00088 a = a->findAndCompress();
00089 b = b->findAndCompress();
00090 if (a == b)
00091 return 0;
00092
00093 if (a > b)
00094 std::swap(a, b);
00095 if (__sync_bool_compare_and_swap(&a->m_component, a, b)) {
00096 return b;
00097 }
00098 }
00099 }
00100 };
00101 }
00102 #endif