raphtory-core 0.18.5

Raphtory core components
Documentation
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicI64, Ordering};

pub trait TimeCounterTrait {
    fn cmp(a: i64, b: i64) -> bool;
    fn counter(&self) -> &AtomicI64;

    fn update(&self, new_value: i64) {
        let mut current_value = self.get();
        while Self::cmp(new_value, current_value) {
            match self.counter().compare_exchange_weak(
                current_value,
                new_value,
                Ordering::Relaxed,
                Ordering::Relaxed,
            ) {
                Ok(_) => break,
                Err(value) => current_value = value,
            }
        }
    }
    #[inline(always)]
    fn get(&self) -> i64 {
        self.counter().load(Ordering::Relaxed)
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct MinCounter {
    counter: AtomicI64,
}

impl Default for MinCounter {
    fn default() -> Self {
        Self::new()
    }
}

impl From<i64> for MinCounter {
    fn from(value: i64) -> Self {
        let counter = AtomicI64::new(value);
        Self { counter }
    }
}

impl MinCounter {
    pub fn new() -> Self {
        Self {
            counter: AtomicI64::new(i64::MAX),
        }
    }
}

impl TimeCounterTrait for MinCounter {
    fn cmp(new_value: i64, current_value: i64) -> bool {
        new_value < current_value
    }

    #[inline(always)]
    fn counter(&self) -> &AtomicI64 {
        &self.counter
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct MaxCounter {
    counter: AtomicI64,
}

impl From<i64> for MaxCounter {
    fn from(value: i64) -> Self {
        let counter = AtomicI64::new(value);
        Self { counter }
    }
}

impl Default for MaxCounter {
    fn default() -> Self {
        Self::new()
    }
}

impl MaxCounter {
    pub fn new() -> Self {
        Self {
            counter: AtomicI64::new(i64::MIN),
        }
    }
}

impl TimeCounterTrait for MaxCounter {
    fn cmp(a: i64, b: i64) -> bool {
        a > b
    }
    #[inline(always)]
    fn counter(&self) -> &AtomicI64 {
        &self.counter
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn min_counter() {
        let counter = MinCounter::new();
        counter.update(0);
        assert_eq!(counter.get(), 0);
        counter.update(1);
        assert_eq!(counter.get(), 0);
        counter.update(0);
        assert_eq!(counter.get(), 0);
        counter.update(-1);
        assert_eq!(counter.get(), -1);
    }

    #[test]
    fn max_counter() {
        let counter = MaxCounter::new();
        counter.update(0);
        assert_eq!(counter.get(), 0);
        counter.update(-1);
        assert_eq!(counter.get(), 0);
        counter.update(0);
        assert_eq!(counter.get(), 0);
        counter.update(1);
        assert_eq!(counter.get(), 1);
    }
}