1use std::fmt;
2use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
3use std::sync::Arc;
4
5pub trait Sequencer: fmt::Debug {
7 fn next_sequence_number(&self) -> u16;
8 fn roll_over_count(&self) -> u64;
9 fn clone_to(&self) -> Box<dyn Sequencer>;
10}
11
12impl Clone for Box<dyn Sequencer> {
13 fn clone(&self) -> Box<dyn Sequencer> {
14 self.clone_to()
15 }
16}
17
18pub fn new_random_sequencer() -> impl Sequencer {
21 let c = Counters {
22 sequence_number: Arc::new(AtomicU16::new(rand::random::<u16>())),
23 roll_over_count: Arc::new(AtomicU64::new(0)),
24 };
25 SequencerImpl(c)
26}
27
28pub fn new_fixed_sequencer(s: u16) -> impl Sequencer {
31 let sequence_number = if s == 0 { u16::MAX } else { s - 1 };
32
33 let c = Counters {
34 sequence_number: Arc::new(AtomicU16::new(sequence_number)),
35 roll_over_count: Arc::new(AtomicU64::new(0)),
36 };
37
38 SequencerImpl(c)
39}
40
41#[derive(Debug, Clone)]
42struct SequencerImpl(Counters);
43
44#[derive(Debug, Clone)]
45struct Counters {
46 sequence_number: Arc<AtomicU16>,
47 roll_over_count: Arc<AtomicU64>,
48}
49
50impl Sequencer for SequencerImpl {
51 fn next_sequence_number(&self) -> u16 {
54 if self.0.sequence_number.load(Ordering::SeqCst) == u16::MAX {
55 self.0.roll_over_count.fetch_add(1, Ordering::SeqCst);
56 self.0.sequence_number.store(0, Ordering::SeqCst);
57 0
58 } else {
59 self.0.sequence_number.fetch_add(1, Ordering::SeqCst) + 1
60 }
61 }
62
63 fn roll_over_count(&self) -> u64 {
66 self.0.roll_over_count.load(Ordering::SeqCst)
67 }
68
69 fn clone_to(&self) -> Box<dyn Sequencer> {
70 Box::new(self.clone())
71 }
72}