kairoi 0.2.2

Another application-level tracing library
Documentation
use dashmap::DashMap;
use std::ops::{Deref, DerefMut};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::AcqRel;
use std::sync::{Arc, Weak};
use parking_lot::Mutex;

#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Hash)]
pub struct Id(usize);

impl Id {
    fn new() -> Self {
        static ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
        Self(ID_COUNTER.fetch_add(1, AcqRel))
    }
}

pub struct Node<T: Send + Sync> {
    id: Id,
    value: Mutex<Arc<T>>,
    depth: usize,
    parent: Weak<Node<T>>,
    children: DashMap<Id, Arc<Node<T>>>,
}

impl<T: Send + Sync> Node<T> {
    pub fn new(value: T) -> Self {
        Self {
            id: Id::new(),
            value: Mutex::new(Arc::new(value)),
            depth: 0,
            parent: Weak::new(),
            children: DashMap::new(),
        }
    }


    pub fn id(&self) -> Id {
        self.id
    }

    pub fn value(&self) -> Arc<T> {
        self.value.lock().clone()
    }

    pub fn depth(&self) -> usize {
        self.depth
    }

    pub fn parent(&self) -> Option<Arc<Self>> {
        self.parent.upgrade()
    }

    pub fn children(&self) -> impl Iterator<Item = Arc<Self>> {
        self.children.iter().map(|v| v.deref().clone())
    }


    pub fn find<F: Fn(&Self) -> bool>(self: &Arc<Self>, f: F) -> Option<Arc<Self>> {
        if f(self) {
            return Some(self.clone());
        }

        for item in self.children.iter() {
            if let Some(found) = item.find(&f) {
                return Some(found);
            }
        }

        None
    }

    fn find_all_into<F: Fn(&Self) -> bool>(self: &Arc<Self>, f: F, v: &mut Vec<Arc<Self>>) {
        if f(self) {
            v.push(self.clone());
        }

        for item in self.children.iter() {
            item.find_all_into(&f, v);
        }
    }

    pub fn find_all<F: Fn(&Self) -> bool>(self: &Arc<Self>, f: F) -> Vec<Arc<Self>> {
        let mut v: Vec<Arc<Self>> = Vec::new();
        self.find_all_into(f, &mut v);
        v
    }


    pub fn add(self: &Arc<Self>, mut child: Self) -> Arc<Self> {
        child.parent = Arc::downgrade(self);
        child.depth = self.depth + 1;
        let child_ref = Arc::new(child);
        self.children.insert(child_ref.id, child_ref.clone());
        child_ref
    }

    pub fn update(&self, value: T) {
        *self.value.lock().deref_mut() = Arc::new(value);
    }

    pub fn delete(&self) {
        if let Some(parent) = self.parent.upgrade() {
            parent.children.remove(&self.id);
        }
    }
}