use filecoin_proofs::{
with_shape, SECTOR_SIZE_16_MIB, SECTOR_SIZE_1_GIB, SECTOR_SIZE_2_KIB, SECTOR_SIZE_32_GIB,
SECTOR_SIZE_4_KIB, SECTOR_SIZE_512_MIB, SECTOR_SIZE_64_GIB, SECTOR_SIZE_8_MIB,
};
use generic_array::typenum::Unsigned;
use storage_proofs_core::merkle::MerkleTreeTrait;
fn canonical_shape(sector_size: u64) -> (usize, usize, usize) {
assert_eq!(sector_size.count_ones(), 1);
let log_byte_size = sector_size.trailing_zeros();
let log_nodes = log_byte_size - 5;
let max_tree_log = 3;
let log_max_base = 27; let log_base = max_tree_log; let log_in_base = u32::min(log_max_base, (log_nodes / log_base) * log_base);
let log_upper = log_nodes - log_in_base; let log_rem = log_upper % max_tree_log;
let (log_sub, log_top) = {
if log_upper > 0 {
if log_rem == 0 {
(Some(max_tree_log), None) } else {
if log_upper > max_tree_log {
(Some(max_tree_log), Some(log_rem))
} else {
(Some(log_rem), None)
}
}
} else {
(None, None)
}
};
let base = 1 << log_base;
let sub = if let Some(l) = log_sub { 1 << l } else { 0 };
let top = if let Some(l) = log_top { 1 << l } else { 0 };
(base, sub, top)
}
fn arities_to_usize<Tree: MerkleTreeTrait>() -> (usize, usize, usize) {
(
Tree::Arity::to_usize(),
Tree::SubTreeArity::to_usize(),
Tree::TopTreeArity::to_usize(),
)
}
#[test]
fn test_with_shape_macro() {
test_with_shape_macro_aux(SECTOR_SIZE_2_KIB);
test_with_shape_macro_aux(SECTOR_SIZE_4_KIB);
test_with_shape_macro_aux(SECTOR_SIZE_8_MIB);
test_with_shape_macro_aux(SECTOR_SIZE_16_MIB);
test_with_shape_macro_aux(SECTOR_SIZE_512_MIB);
test_with_shape_macro_aux(SECTOR_SIZE_1_GIB);
test_with_shape_macro_aux(SECTOR_SIZE_32_GIB);
test_with_shape_macro_aux(SECTOR_SIZE_64_GIB);
}
fn test_with_shape_macro_aux(sector_size: u64) {
let expected = canonical_shape(sector_size);
let arities = with_shape!(sector_size, arities_to_usize);
assert_eq!(
arities, expected,
"Wrong shape for sector size {}: have {:?} but need {:?}.",
sector_size, arities, expected
);
}