60 for(uint32_t i = 0; i <
size; ++i)
61 mData[i] = (uint32_t)i;
64 uint32_t
find(uint32_t
id)
const {
66 uint64_t value =
mData[id];
67 uint32_t new_parent =
parent((uint32_t)value);
68 uint64_t new_value = (value & 0xFFFFFFFF00000000ULL) | new_parent;
70 if(value != new_value)
71 mData[id].compare_exchange_weak(value, new_value);
77 bool same(uint32_t id1, uint32_t id2)
const {
88 uint32_t
unite(uint32_t id1, uint32_t id2) {
96 uint32_t r1 =
rank(id1), r2 =
rank(id2);
98 if(r1 > r2 || (r1 == r2 && id1 < id2)) {
103 uint64_t oldEntry = ((uint64_t)r1 << 32) | id1;
104 uint64_t newEntry = ((uint64_t)r1 << 32) | id2;
106 if(!
mData[id1].compare_exchange_strong(oldEntry, newEntry))
110 oldEntry = ((uint64_t)r2 << 32) | id2;
111 newEntry = ((uint64_t)(r2 + 1) << 32) | id2;
113 mData[id2].compare_exchange_weak(oldEntry, newEntry);
129 const uint64_t lock_flag = 1ULL << 63;
131 uint64_t value =
mData[id];
132 if((value & lock_flag) || (uint32_t)value !=
id)
135#if defined(__i386__) || defined(__amd64__)
136 __asm__ __volatile__(
"pause\n");
138 return mData[id].compare_exchange_strong(value, value | lock_flag);
142 const uint64_t lock_flag = 1ULL << 63;
143 mData[id] &= ~lock_flag;
151 uint32_t r1 =
rank(id1), r2 =
rank(id2);
152 return (r1 > r2 || (r1 == r2 && id1 < id2)) ? id1 : id2;
160 uint32_t r1 =
rank(id1), r2 =
rank(id2);
162 if(r1 > r2 || (r1 == r2 && id1 < id2)) {
167 mData[id1] = ((uint64_t)r1 << 32) | id2;
168 mData[id2] = ((uint64_t)(r2 + ((r1 == r2) ? 1 : 0)) << 32) | id2;
174 return (uint32_t)
mData.size();
177 uint32_t
rank(uint32_t
id)
const {
178 return ((uint32_t)(
mData[
id] >> 32)) & 0x7FFFFFFFu;
182 return (uint32_t)
mData[id];
189 mutable std::vector<std::atomic<uint64_t>>
mData;
bool same(uint32_t id1, uint32_t id2) const
uint32_t unite(uint32_t id1, uint32_t id2)
uint32_t find(uint32_t id) const
bool isRoot(uint32_t id) const
bool try_lock(uint32_t &id)
uint32_t parent(uint32_t id) const
uint32_t unite_index_locked(uint32_t id1, uint32_t id2) const
uint32_t unite_unlock(uint32_t id1, uint32_t id2)
uint32_t rank(uint32_t id) const
DisjointSets(uint32_t size)
std::vector< std::atomic< uint64_t > > mData