rocketmq_client_rust/common/
thread_local_index.rs1#![allow(clippy::missing_const_for_thread_local)]
19use std::cell::RefCell;
20use std::fmt;
21
22use rand::Rng;
23
24thread_local! {
25 static THREAD_LOCAL_INDEX: RefCell<Option<i32>> = const {RefCell::new(None)};
26}
27
28const POSITIVE_MASK: i32 = 0x7FFFFFFF;
29const MAX: i32 = i32::MAX;
30
31#[derive(Default, Clone)]
32pub struct ThreadLocalIndex;
33
34impl ThreadLocalIndex {
35 pub fn increment_and_get(&self) -> i32 {
36 THREAD_LOCAL_INDEX.with(|index| {
37 let mut index = index.borrow_mut();
38 let new_value = match *index {
39 Some(val) => val.wrapping_add(1) & POSITIVE_MASK,
40 None => rand::rng().random_range(0..=MAX) & POSITIVE_MASK,
41 };
42 *index = Some(new_value);
43 new_value
44 })
45 }
46
47 pub fn reset(&self) {
48 let new_value = rand::rng().random_range(0..=MAX).abs();
49 THREAD_LOCAL_INDEX.with(|index| {
50 *index.borrow_mut() = Some(new_value);
51 });
52 }
53}
54
55impl fmt::Display for ThreadLocalIndex {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 THREAD_LOCAL_INDEX.with(|index| {
58 write!(
59 f,
60 "ThreadLocalIndex {{ thread_local_index={} }}",
61 index.borrow().unwrap_or(0)
62 )
63 })
64 }
65}