use crate::numeric_id::NumericId;
use atomic_int::AtomicInt;
pub(crate) mod atomic_int;
pub(crate) mod buffer;
pub(crate) mod uf;
#[cfg(test)]
mod tests;
pub struct UnionFind<T: NumericId> {
inner: uf::ConcurrentUnionFind<T::Atomic>,
}
impl<T: NumericId> Clone for UnionFind<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T: NumericId> Default for UnionFind<T>
where
T::Atomic: AtomicInt,
{
fn default() -> Self {
Self {
inner: Default::default(),
}
}
}
impl<T: NumericId> UnionFind<T>
where
T::Atomic: AtomicInt<Underlying = T::Rep>,
{
pub fn reset(&self) {
self.inner.reset();
}
pub fn deep_copy(&self) -> Self {
Self {
inner: self.inner.deep_copy(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: uf::ConcurrentUnionFind::with_capacity(capacity),
}
}
pub fn find(&self, elt: T) -> T {
T::new(self.inner.find(elt.rep()))
}
pub fn same_set(&self, l: T, r: T) -> bool {
self.inner.same_set(l.rep(), r.rep())
}
pub fn union(&self, l: T, r: T) -> (T, T) {
let (parent, child) = self.inner.merge(l.rep(), r.rep());
(T::new(parent), T::new(child))
}
}