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;
25#[cfg(feature = "encryption")]
26pub mod crypt;
27pub mod digest;
28pub mod exec;
29pub mod filemap;
30pub mod inode_bitmap;
31pub mod logger;
32pub mod metrics;
33pub mod mpmc;
34pub mod reader;
35pub mod trace;
36pub mod types;
37pub mod verity;
38
39pub fn div_round_up(n: u64, d: u64) -> u64 {
41 debug_assert!(d != 0);
42 debug_assert!(d.is_power_of_two());
43 (n + d - 1) / d
44}
45
46pub fn round_up(n: u64, d: u64) -> u64 {
48 debug_assert!(d != 0);
49 debug_assert!(d.is_power_of_two());
50 (n + d - 1) / d * d
51}
52
53pub fn round_up_usize(n: usize, d: usize) -> usize {
55 debug_assert!(d != 0);
56 debug_assert!(d.is_power_of_two());
57 (n + d - 1) / d * d
58}
59
60pub fn try_round_up_4k<U: TryFrom<u64>, T: Into<u64>>(x: T) -> Option<U> {
62 let t = 4095u64;
63 if let Some(v) = x.into().checked_add(t) {
64 let z = v & (!t);
65 z.try_into().ok()
66 } else {
67 None
68 }
69}
70
71pub fn round_down_4k(x: u64) -> u64 {
72 x & (!4095u64)
73}
74
75pub fn round_down(n: u64, d: u64) -> u64 {
77 debug_assert!(d != 0);
78 debug_assert!(d.is_power_of_two());
79 n / d * d
80}
81
82pub enum DelayType {
83 Fixed,
84 BackOff,
86}
87
88pub struct Delayer {
89 r#type: DelayType,
90 attempts: u32,
91 time: Duration,
92}
93
94impl Delayer {
95 pub fn new(t: DelayType, time: Duration) -> Self {
96 Delayer {
97 r#type: t,
98 attempts: 0,
99 time,
100 }
101 }
102
103 pub fn delay(&mut self) {
104 use std::thread::sleep;
105
106 match self.r#type {
107 DelayType::Fixed => sleep(self.time),
108 DelayType::BackOff => sleep((1 << self.attempts) * self.time),
109 }
110 self.attempts += 1;
111 }
112}
113
114struct LazyDrop<T> {
115 v: T,
116}
117
118unsafe impl<T> Send for LazyDrop<T> {}
119
120pub fn lazy_drop<T: 'static>(v: T) {
122 let v = LazyDrop { v };
123 std::thread::spawn(move || {
124 std::thread::sleep(Duration::from_secs(600));
125 let _ = v.v;
126 });
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_rounders() {
135 assert_eq!(round_down_4k(0), 0);
136 assert_eq!(round_down_4k(100), 0);
137 assert_eq!(round_down_4k(4300), 4096);
138 assert_eq!(round_down_4k(4096), 4096);
139 assert_eq!(round_down_4k(4095), 0);
140 assert_eq!(round_down_4k(4097), 4096);
141 assert_eq!(round_down_4k(u64::MAX - 1), u64::MAX - 4095);
142 assert_eq!(round_down_4k(u64::MAX - 4095), u64::MAX - 4095);
143 assert_eq!(try_round_up_4k::<i32, _>(0u32), Some(0i32));
145 assert_eq!(try_round_up_4k::<u32, _>(0u32), Some(0u32));
146 assert_eq!(try_round_up_4k::<u32, _>(1u32), Some(4096u32));
147 assert_eq!(try_round_up_4k::<u32, _>(100u32), Some(4096u32));
148 assert_eq!(try_round_up_4k::<u32, _>(4100u32), Some(8192u32));
149 assert_eq!(try_round_up_4k::<u32, _>(4096u32), Some(4096u32));
150 assert_eq!(try_round_up_4k::<u32, _>(4095u32), Some(4096u32));
151 assert_eq!(try_round_up_4k::<u32, _>(4097u32), Some(8192u32));
152 assert_eq!(try_round_up_4k::<u32, _>(u32::MAX), None);
153 assert_eq!(try_round_up_4k::<u64, _>(u32::MAX), Some(0x1_0000_0000u64));
154 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 1), None);
155 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX), None);
156 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 4097), None);
157 assert_eq!(
159 try_round_up_4k::<u64, _>(u64::MAX - 4096),
160 Some(u64::MAX - 4095)
161 );
162 assert_eq!(try_round_up_4k::<u64, _>(u64::MAX - 1), None);
164 assert_eq!(try_round_up_4k::<u32, _>(u64::MAX - 4096), None);
166 }
167}