hlc-gen 2.0.0

Lock-free Hybrid Logical Clock (HLC) timestamp generator.
Documentation
use core::sync::atomic::{AtomicI64, Ordering};

use chrono::Utc;

use crate::epoch::EPOCH;

/// Provides current time.
pub trait ClockSource: Default {
    /// The current timestamp in milliseconds since the Unix epoch.
    fn current_timestamp(&self) -> i64;
}

/// UTC clock.
///
/// Granularity is in milliseconds.
#[derive(Default)]
pub struct UtcClock;

impl ClockSource for UtcClock {
    fn current_timestamp(&self) -> i64 {
        Utc::now().timestamp_millis()
    }
}

/// Manual clock.
///
/// Useful for testing purposes.
pub struct ManualClock {
    /// The current timestamp in milliseconds since the Unix epoch.
    timestamp: AtomicI64,
}

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

impl ClockSource for ManualClock {
    fn current_timestamp(&self) -> i64 {
        self.timestamp.load(Ordering::SeqCst)
    }
}

impl ManualClock {
    /// Creates new clock.
    pub fn new(timestamp: i64) -> Self {
        Self {
            timestamp: AtomicI64::new(timestamp),
        }
    }

    /// Sets the current timestamp.
    pub fn set_current_timestamp(&self, timestamp: i64) {
        self.timestamp.store(timestamp, Ordering::SeqCst);
    }
}