k_snowflake/
context.rs

1use crate::constants::TWITTER_EPOCH_START;
2use once_cell::sync::Lazy;
3use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering};
4use std::sync::Arc;
5
6pub static CONTEXT: Lazy<Arc<Context>> = Lazy::new(|| Arc::new(Context::new()));
7
8pub struct Context {
9    pub epoch_start: AtomicU64,
10    pub sequence: AtomicU16,
11    pub instance: AtomicU16,
12    pub sequence_autoincrement: AtomicBool,
13}
14
15impl Context {
16    fn new() -> Self {
17        Self {
18            epoch_start: AtomicU64::new(TWITTER_EPOCH_START),
19            instance: AtomicU16::new((std::process::id() & 0x3FF) as u16),
20            sequence: AtomicU16::new(0),
21            sequence_autoincrement: AtomicBool::new(true),
22        }
23    }
24}
25
26pub fn sequence_increment() {
27    CONTEXT.sequence.store(
28        (CONTEXT.sequence.load(Ordering::Relaxed) + 1) & 0xFFF,
29        Ordering::Relaxed,
30    );
31}
32
33pub fn set_instance(instance: u16) {
34    CONTEXT.instance.store(instance, Ordering::Relaxed);
35}
36
37pub fn set_sequence(sequence: u16) {
38    CONTEXT.sequence.store(sequence, Ordering::Relaxed);
39}
40
41/// Set sequence number autoincrement on every snowflake creation from context.
42/// Default: true
43pub fn set_sequence_autoincrement(sequence_autoincrement: bool) {
44    CONTEXT
45        .sequence_autoincrement
46        .store(sequence_autoincrement, Ordering::Relaxed);
47}
48
49pub fn set_epoch(epoch: u64) {
50    // *CONTEXT.epoch_start.write().unwrap() = epoch;
51    CONTEXT.epoch_start.store(epoch, Ordering::Relaxed);
52}