1#[macro_use]
6extern crate log;
7#[macro_use]
8extern crate serde;
9#[macro_use]
10extern crate lazy_static;
11#[macro_use]
12extern crate nydus_api;
13
14use std::convert::{Into, TryFrom, TryInto};
15use std::time::Duration;
16
17pub use self::exec::*;
18pub use self::inode_bitmap::InodeBitmap;
19pub use self::reader::*;
20pub use self::types::*;
21
22pub mod async_helper;
23pub mod compact;
24pub mod compress;
25pub mod crc32;
26#[cfg(feature = "encryption")]
27pub mod crypt;
28pub mod digest;
29pub mod exec;
30pub mod filemap;
31pub mod inode_bitmap;
32pub mod logger;
33pub mod metrics;
34pub mod mpmc;
35pub mod reader;
36pub mod trace;
37pub mod types;
38pub mod verity;
39
40pub fn div_round_up(n: u64, d: u64) -> u64 {
42 debug_assert!(d != 0);
43 debug_assert!(d.is_power_of_two());
44 n.div_ceil(d)
45}
46
47pub fn round_up(n: u64, d: u64) -> u64 {
49 debug_assert!(d != 0);
50 debug_assert!(d.is_power_of_two());
51 n.div_ceil(d) * d
52}
53
54pub fn round_up_usize(n: usize, d: usize) -> usize {
56 debug_assert!(d != 0);
57 debug_assert!(d.is_power_of_two());
58 n.div_ceil(d) * d
59}
60
61pub fn try_round_up_4k<U: TryFrom<u64>, T: Into<u64>>(x: T) -> Option<U> {
63 let t = 4095u64;
64 if let Some(v) = x.into().checked_add(t) {
65 let z = v & (!t);
66 z.try_into().ok()
67 } else {
68 None
69 }
70}
71
72pub fn round_down_4k(x: u64) -> u64 {
73 x & (!4095u64)
74}
75
76pub fn round_down(n: u64, d: u64) -> u64 {
78 debug_assert!(d != 0);
79 debug_assert!(d.is_power_of_two());
80 n / d * d
81}
82
83pub enum DelayType {
84 Fixed,
85 BackOff,
87}
88
89pub struct Delayer {
90 r#type: DelayType,
91 attempts: u32,
92 time: Duration,
93}
94
95impl Delayer {
96 pub fn new(t: DelayType, time: Duration) -> Self {
97 Delayer {
98 r#type: t,
99 attempts: 0,
100 time,
101 }
102 }
103
104 pub fn delay(&mut self) {
105 use std::thread::sleep;
106
107 match self.r#type {
108 DelayType::Fixed => sleep(self.time),
109 DelayType::BackOff => sleep((1 << self.attempts) * self.time),
110 }
111 self.attempts += 1;
112 }
113}
114
115struct LazyDrop<T> {
116 v: T,
117}
118
119unsafe impl<T> Send for LazyDrop<T> {}
120
121pub fn lazy_drop<T: 'static>(v: T) {
123 let v = LazyDrop { v };
124 std::thread::spawn(move || {
125 std::thread::sleep(Duration::from_secs(600));
126 let _ = v.v;
127 });
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn test_rounders() {
136 assert_eq!(round_down_4k(0), 0);
137 assert_eq!(round_down_4k(100), 0);
138 assert_eq!(round_down_4k(4300), 4096);
139 assert_eq!(round_down_4k(4096), 4096);
140 assert_eq!(round_down_4k(4095), 0);
141 assert_eq!(round_down_4k(4097), 4096);
142 assert_eq!(round_down_4k(u64::MAX - 1), u64::MAX - 4095);
143 assert_eq!(round_down_4k(u64::MAX - 4095), u64::MAX - 4095);
144 assert_eq!(try_round_up_4k::<i32, _>(0u32), Some(0i32));
146 assert_eq!(try_round_up_4k::<u32, _>(0u32), Some(0u32));
147 assert_eq!(try_round_up_4k::<u32, _>(1u32), Some(4096u32));
148 assert_eq!(try_round_up_4k::<u32, _>(100u32), Some(4096u32));
149 assert_eq!(try_round_up_4k::<u32, _>(4100u32), Some(8192u32));
150 assert_eq!(try_round_up_4k::<u32, _>(4096u32), Some(4096u32));
151 assert_eq!(try_round_up_4k::<u32, _>(4095u32), Some(4096u32));
152 assert_eq!(try_round_up_4k::<u32, _>(4097u32), Some(8192u32));
153 assert_eq!(try_round_up_4k::<u32, _>(u32::MAX), None);
154 assert_eq!(try_round_up_4k::<u64, _>(u32::MAX), Some(0x1_0000_0000u64));
155 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 1), None);
156 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX), None);
157 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 4097), None);
158 assert_eq!(
160 try_round_up_4k::<u64, _>(u64::MAX - 4096),
161 Some(u64::MAX - 4095)
162 );
163 assert_eq!(try_round_up_4k::<u64, _>(u64::MAX - 1), None);
165 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 4096), None);
167 }
168
169 #[test]
170 fn test_round_up_usize() {
171 assert_eq!(round_up_usize(10, 8), 16);
172 assert_eq!(round_up_usize(100, 8), 104);
173 assert_eq!(round_up_usize(1000, 8), 1000);
174 }
175}