1pub fn is_pwr_two(n: u64) -> bool {
5 n & (n - 1) == 0
6}
7
8pub fn pad_bytes<const ALIGN: usize>(n: usize) -> usize {
9 debug_assert!(is_pwr_two(ALIGN as u64));
10 (ALIGN - (n & (ALIGN - 1))) & (ALIGN - 1)
11}
12
13pub fn pad_bytes_to(n: usize, align: usize) -> usize {
14 debug_assert!(is_pwr_two(align as u64));
15 (align - (n & (align - 1))) & (align - 1)
16}
17
18pub fn pad_bytes_u64<const ALIGN: u64>(n: u64) -> u64 {
19 debug_assert!(is_pwr_two(ALIGN));
20 (ALIGN - (n & (ALIGN - 1))) & (ALIGN - 1)
21}
22
23const LOG_TABLE_256: [u8; 256] = [
25 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
26 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
27 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
28 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
29 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
30 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
31 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
32 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
33];
34
35pub fn log_2_ceil(val: u32) -> u32 {
39 assert!(val > 0);
40 let upper_half = val >> 16;
41 if upper_half == 0 {
42 let third_quarter = val >> 8;
43 if third_quarter == 0 {
44 LOG_TABLE_256[val as usize] as u32
46 } else {
47 LOG_TABLE_256[third_quarter as usize] as u32 + 8
49 }
50 } else {
51 let first_quarter = upper_half >> 8;
52 if first_quarter == 0 {
53 16 + LOG_TABLE_256[upper_half as usize] as u32
55 } else {
56 24 + LOG_TABLE_256[first_quarter as usize] as u32
58 }
59 }
60}
61
62#[cfg(test)]
63pub mod tests {
64 use crate::utils::bit::log_2_ceil;
65
66 #[test]
67 fn test_log_2_ceil() {
68 fn classic_approach(mut val: u32) -> u32 {
69 let mut counter = 0;
70 while val > 0 {
71 val >>= 1;
72 counter += 1;
73 }
74 counter
75 }
76
77 for i in 1..(16 * 1024) {
78 assert_eq!(log_2_ceil(i), classic_approach(i));
79 }
80 assert_eq!(log_2_ceil(50 * 1024), classic_approach(50 * 1024));
81 assert_eq!(
82 log_2_ceil(1024 * 1024 * 1024),
83 classic_approach(1024 * 1024 * 1024)
84 );
85 }
86}