1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use crate::constants;
67/// Returns the smallest order such that (MIN_ORDER_SHIFT << order) >= size.
8/// Size must be non zero.
9pub fn fit_order(size: usize) -> usize {
10// Safety: `leading_zeros` returns a u32, so this is safe promotion
11(std::mem::size_of::<usize>() * 8 - (size - 1).leading_zeros() as usize)
12 .saturating_sub(constants::MIN_ORDER_SHIFT)
13}
1415/// Get size in bytes of a given |order|.
16pub fn order_to_size(order: u8) -> usize {
17 constants::MIN_ORDER_SIZE << order
18}
1920/// Get the necessary |block size| to fit the given |payload_size| in range
21/// MIN_ORDER_SIZE <= block size <= MAX_ORDER_SIZE
22pub fn block_size_for_payload(payload_size: usize) -> usize {
23 (payload_size + constants::HEADER_SIZE_BYTES)
24 .clamp(constants::MIN_ORDER_SIZE, constants::MAX_ORDER_SIZE)
25}
2627/// Get the size in bytes for the payload section of a block of the given |order|.
28pub fn payload_size_for_order(order: u8) -> usize {
29 order_to_size(order) - constants::HEADER_SIZE_BYTES
30}
3132#[cfg(test)]
33mod test {
34use super::*;
3536#[test]
37fn fit_order_test() {
38assert_eq!(0, fit_order(1));
39assert_eq!(0, fit_order(16));
40assert_eq!(1, fit_order(17));
41assert_eq!(2, fit_order(33));
42assert_eq!(7, fit_order(2048));
43 }
4445#[test]
46fn order_to_size_test() {
47assert_eq!(16, order_to_size(0));
48assert_eq!(32, order_to_size(1));
49assert_eq!(64, order_to_size(2));
50assert_eq!(128, order_to_size(3));
51assert_eq!(256, order_to_size(4));
52assert_eq!(512, order_to_size(5));
53assert_eq!(1024, order_to_size(6));
54assert_eq!(2048, order_to_size(7));
55 }
5657#[test]
58fn fit_payload_test() {
59for payload_size in 0..500 {
60let block_size = block_size_for_payload(payload_size);
61let order = fit_order(block_size) as u8;
62let payload_max = payload_size_for_order(order);
63assert!(
64 payload_size <= payload_max,
65"Needed {} bytes for a payload, but only got {}; block size {}, order {}",
66 payload_size,
67 payload_max,
68 block_size,
69 order
70 );
71 }
72 }
73}