Upgrade rand and rand_chacha (bench deps) to 0.9 (#798)
1// As each benchmark suite is compiled as a separate crate and uses different helpers, we end up with a bunch
2// of false positives for this lint. So let's just disable it for this code.
3#![allow(dead_code)]
4
5pub mod taffy_helpers;
6pub use taffy_helpers::TaffyTreeBuilder;
7
8#[cfg(feature = "taffy03")]
9pub mod taffy_03_helpers;
10
11#[cfg(feature = "yoga")]
12pub mod yoga_helpers;
13#[cfg(feature = "yoga")]
14pub use yoga_helpers::YogaTreeBuilder;
15
16use rand::distr::uniform::SampleRange;
17use rand::{Rng, SeedableRng};
18use rand_chacha::ChaCha8Rng;
19use taffy::style::Style as TaffyStyle;
20
21pub const STANDARD_RNG_SEED: u64 = 12345;
22
23pub trait GenStyle<Style: Default>: Clone {
24 fn create_leaf_style(&mut self, rng: &mut impl Rng) -> Style;
25 fn create_container_style(&mut self, rng: &mut impl Rng) -> Style;
26 fn create_root_style(&mut self, _rng: &mut impl Rng) -> Style {
27 Default::default()
28 }
29}
30
31#[derive(Clone)]
32pub struct FixedStyleGenerator(pub TaffyStyle);
33impl GenStyle<TaffyStyle> for FixedStyleGenerator {
34 fn create_leaf_style(&mut self, _rng: &mut impl Rng) -> TaffyStyle {
35 self.0.clone()
36 }
37 fn create_container_style(&mut self, _rng: &mut impl Rng) -> TaffyStyle {
38 self.0.clone()
39 }
40}
41
42pub trait BuildTree<R: Rng, G: GenStyle<TaffyStyle>> {
43 const NAME: &'static str;
44 type Tree;
45 type Node: Clone;
46
47 fn with_rng(rng: R, style_generator: G) -> Self;
48
49 fn compute_layout_inner(&mut self, available_width: Option<f32>, available_height: Option<f32>);
50 fn random_usize(&mut self, range: impl SampleRange<usize>) -> usize;
51 fn create_leaf_node(&mut self) -> Self::Node;
52 fn create_container_node(&mut self, children: &[Self::Node]) -> Self::Node;
53 fn set_root_children(&mut self, children: &[Self::Node]);
54 fn total_node_count(&mut self) -> usize;
55 fn into_tree_and_root(self) -> (Self::Tree, Self::Node);
56
57 fn build_n_leaf_nodes(&mut self, n: usize) -> Vec<Self::Node> {
58 (0..n).map(|_| self.create_leaf_node()).collect()
59 }
60
61 /// A helper function to recursively construct a deep tree
62 fn build_deep_tree(&mut self, max_nodes: u32, branching_factor: u32) -> Vec<Self::Node> {
63 if max_nodes <= branching_factor {
64 // Build leaf nodes
65 return (0..max_nodes).map(|_| self.create_leaf_node()).collect();
66 }
67
68 // Add another layer to the tree
69 // Each child gets an equal amount of the remaining nodes
70 (0..branching_factor)
71 .map(|_| {
72 let max_nodes = (max_nodes - branching_factor) / branching_factor;
73 let children = self.build_deep_tree(max_nodes, branching_factor);
74 self.create_container_node(&children)
75 })
76 .collect()
77 }
78}
79
80pub trait BuildTreeExt<G: GenStyle<TaffyStyle>>: BuildTree<ChaCha8Rng, G> {
81 fn with_seed(seed: u64, style_generator: G) -> Self
82 where
83 Self: Sized,
84 {
85 let rng = ChaCha8Rng::seed_from_u64(seed);
86 Self::with_rng(rng, style_generator)
87 }
88
89 fn new(style_generator: G) -> Self
90 where
91 Self: Sized,
92 {
93 Self::with_seed(STANDARD_RNG_SEED, style_generator)
94 }
95
96 /// A helper function to recursively construct a deep tree
97 fn build_super_deep_hierarchy(&mut self, depth: u32, nodes_per_level: u32) {
98 let mut children = Vec::with_capacity(nodes_per_level as usize);
99 for _ in 0..depth {
100 let node_with_children = self.create_container_node(&children);
101
102 children.clear();
103 children.push(node_with_children);
104 for _ in 0..(nodes_per_level - 1) {
105 children.push(self.create_leaf_node())
106 }
107 }
108 self.set_root_children(&children);
109 }
110
111 /// A tree with a higher depth for a more realistic scenario
112 fn build_deep_hierarchy(&mut self, node_count: u32, branching_factor: u32) {
113 let children = self.build_deep_tree(node_count, branching_factor);
114 self.set_root_children(&children);
115 }
116
117 /// A tree with many children that have shallow depth
118 fn build_flat_hierarchy(&mut self, target_node_count: u32) {
119 let mut children = Vec::new();
120
121 while self.total_node_count() < target_node_count as usize {
122 let count = self.random_usize(1..=4);
123 let sub_children = self.build_n_leaf_nodes(count);
124 let node = self.create_container_node(&sub_children);
125 children.push(node);
126 }
127
128 self.set_root_children(&children);
129 }
130
131 /// Compute layout given a viewport size
132 fn compute_layout(&mut self, available_width: Option<f32>, available_height: Option<f32>) {
133 self.compute_layout_inner(available_width, available_height);
134 }
135}