20#ifndef KICAD_CORE_UNION_FIND_H
21#define KICAD_CORE_UNION_FIND_H
60 if( aCount >
static_cast<size_t>( std::numeric_limits<uint32_t>::max() ) )
61 throw std::length_error(
"KI_UNION_FIND exceeds its 2^32 element limit" );
63 std::vector<std::atomic<uint32_t>> fresh( aCount );
66 for(
size_t ii = 0; ii < aCount; ++ii )
67 m_parent[ii].store(
static_cast<uint32_t
>( ii ), std::memory_order_relaxed );
82 bool Unite(
size_t aA,
size_t aB )
84 uint32_t u =
static_cast<uint32_t
>( aA );
85 uint32_t v =
static_cast<uint32_t
>( aB );
86 uint32_t pu =
m_parent[u].load( std::memory_order_relaxed );
87 uint32_t pv =
m_parent[v].load( std::memory_order_relaxed );
101 if(
m_parent[u].compare_exchange_strong( pu, pv, std::memory_order_acq_rel,
102 std::memory_order_relaxed ) )
114 uint32_t grandparent =
m_parent[pu].load( std::memory_order_relaxed );
118 std::memory_order_acq_rel,
119 std::memory_order_relaxed );
122 pu =
m_parent[u].load( std::memory_order_relaxed );
132 uint32_t x =
static_cast<uint32_t
>( aX );
133 uint32_t p =
m_parent[x].load( std::memory_order_relaxed );
138 p =
m_parent[x].load( std::memory_order_relaxed );
152 uint32_t x =
static_cast<uint32_t
>( aX );
153 uint32_t p =
m_parent[x].load( std::memory_order_relaxed );
157 uint32_t grandparent =
m_parent[p].load( std::memory_order_relaxed );
159 m_parent[x].store( grandparent, std::memory_order_relaxed );
size_t FindCompress(size_t aX)
Shorten the path from aX to its root so that later queries walk less of it.
size_t ComponentCount() const
bool Connected(size_t aA, size_t aB) const
KI_UNION_FIND(size_t aCount)
KI_UNION_FIND & operator=(const KI_UNION_FIND &)=delete
Discard all unions and resize the set to aCount single-element components.
void Reset(size_t aCount)
std::vector< std::atomic< uint32_t > > m_parent
bool Unite(size_t aA, size_t aB)
Merge the components that hold aA and aB.
size_t Find(size_t aX) const
std::atomic< size_t > m_components
KI_UNION_FIND(const KI_UNION_FIND &)=delete
VECTOR3I expected(15, 30, 45)