borrowscope_runtime/tracker/
sampling.rs1use std::sync::atomic::Ordering;
4use super::TRACKER;
5
6pub fn should_sample(rate: f64) -> bool {
7 use std::sync::atomic::AtomicU64;
8
9 static SEED: AtomicU64 = AtomicU64::new(0x853c49e6748fea9b);
11
12 let mut x = SEED.load(Ordering::Relaxed);
14 x ^= x << 13;
15 x ^= x >> 7;
16 x ^= x << 17;
17 SEED.store(x, Ordering::Relaxed);
18
19 (x as f64 / u64::MAX as f64) < rate
21}
22
23#[inline(always)]
40pub fn track_new_sampled<T>(
41 #[cfg_attr(not(feature = "track"), allow(unused_variables))] name: &str,
42 value: T,
43 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
44) -> T {
45 #[cfg(feature = "track")]
46 {
47 if should_sample(sample_rate) {
48 let type_name = std::any::type_name::<T>();
49 let mut tracker = TRACKER.lock();
50 tracker.record_new(name, type_name);
51 }
52 }
53 value
54}
55
56#[inline(always)]
66pub fn track_new_with_id_sampled<T>(
67 #[cfg_attr(not(feature = "track"), allow(unused_variables))] id: usize,
68 #[cfg_attr(not(feature = "track"), allow(unused_variables))] name: &str,
69 #[cfg_attr(not(feature = "track"), allow(unused_variables))] location: &str,
70 value: T,
71 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
72) -> T {
73 #[cfg(feature = "track")]
74 {
75 if should_sample(sample_rate) {
76 let type_name = std::any::type_name::<T>();
77 let mut tracker = TRACKER.lock();
78 tracker.record_new_with_id(id, name, type_name, location);
79 }
80 }
81 value
82}
83
84#[inline(always)]
86pub fn track_borrow_sampled<'a, T: ?Sized>(
87 #[cfg_attr(not(feature = "track"), allow(unused_variables))] name: &str,
88 value: &'a T,
89 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
90) -> &'a T {
91 #[cfg(feature = "track")]
92 {
93 if should_sample(sample_rate) {
94 let mut tracker = TRACKER.lock();
95 tracker.record_borrow(name, "unknown", false);
96 }
97 }
98 value
99}
100
101#[inline(always)]
103pub fn track_borrow_mut_sampled<'a, T: ?Sized>(
104 #[cfg_attr(not(feature = "track"), allow(unused_variables))] name: &str,
105 value: &'a mut T,
106 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
107) -> &'a mut T {
108 #[cfg(feature = "track")]
109 {
110 if should_sample(sample_rate) {
111 let mut tracker = TRACKER.lock();
112 tracker.record_borrow(name, "unknown", true);
113 }
114 }
115 value
116}
117
118#[inline(always)]
120pub fn track_drop_sampled(
121 #[cfg_attr(not(feature = "track"), allow(unused_variables))] name: &str,
122 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
123) {
124 #[cfg(feature = "track")]
125 {
126 if should_sample(sample_rate) {
127 let mut tracker = TRACKER.lock();
128 tracker.record_drop(name);
129 }
130 }
131}
132
133#[inline(always)]
135pub fn track_move_sampled<T>(
136 #[cfg_attr(not(feature = "track"), allow(unused_variables))] from: &str,
137 #[cfg_attr(not(feature = "track"), allow(unused_variables))] to: &str,
138 value: T,
139 #[cfg_attr(not(feature = "track"), allow(unused_variables))] sample_rate: f64,
140) -> T {
141 #[cfg(feature = "track")]
142 {
143 if should_sample(sample_rate) {
144 let mut tracker = TRACKER.lock();
145 tracker.record_move(from, to);
146 }
147 }
148 value
149}
150