1 | //! Ensures that a custom config behaves as the default config, until limits are reached. |
2 | //! Prevents regression after #80. |
3 | |
4 | use crate::{cfg::CfgPrivate, Config, Slab}; |
5 | |
6 | struct CustomConfig; |
7 | |
8 | #[cfg (target_pointer_width = "64" )] |
9 | impl Config for CustomConfig { |
10 | const INITIAL_PAGE_SIZE: usize = 32; |
11 | const MAX_PAGES: usize = 15; |
12 | const MAX_THREADS: usize = 256; |
13 | const RESERVED_BITS: usize = 24; |
14 | } |
15 | |
16 | #[cfg (not(target_pointer_width = "64" ))] |
17 | impl Config for CustomConfig { |
18 | const INITIAL_PAGE_SIZE: usize = 16; |
19 | const MAX_PAGES: usize = 6; |
20 | const MAX_THREADS: usize = 128; |
21 | const RESERVED_BITS: usize = 12; |
22 | } |
23 | |
24 | // We should repeat actions several times to detect invalid lifecycle changes. |
25 | const ITERS: u64 = 5; |
26 | |
27 | #[track_caller ] |
28 | fn slab_eq(mut lhs: Slab<u64, impl Config>, mut rhs: Slab<u64, impl Config>) { |
29 | let mut lhs_vec = lhs.unique_iter().collect::<Vec<_>>(); |
30 | lhs_vec.sort_unstable(); |
31 | let mut rhs_vec = rhs.unique_iter().collect::<Vec<_>>(); |
32 | rhs_vec.sort_unstable(); |
33 | assert_eq!(lhs_vec, rhs_vec); |
34 | } |
35 | |
36 | /// Calls `insert(); remove()` multiple times to detect invalid releasing. |
37 | /// Initially, it revealed bugs in the `Slot::release_with()` implementation. |
38 | #[test] |
39 | fn insert_remove() { |
40 | eprintln!("bits={}; config={:#?}" , usize::BITS, CustomConfig::debug()); |
41 | |
42 | let default_slab = Slab::<u64, _>::new(); |
43 | let custom_slab = Slab::<u64, _>::new_with_config::<CustomConfig>(); |
44 | |
45 | for i in 0..=ITERS { |
46 | let idx = default_slab.insert(i).unwrap(); |
47 | assert!(default_slab.remove(idx)); |
48 | |
49 | let idx = custom_slab.insert(i).unwrap(); |
50 | assert!(custom_slab.remove(idx)); |
51 | } |
52 | |
53 | slab_eq(custom_slab, default_slab); |
54 | } |
55 | |
56 | /// Calls `get()` multiple times to detect invalid ref counting. |
57 | /// Initially, it revealed bugs in the `Slot::get()` implementation. |
58 | #[test] |
59 | fn double_get() { |
60 | eprintln!("bits={}; config={:#?}" , usize::BITS, CustomConfig::debug()); |
61 | |
62 | let default_slab = Slab::<u64, _>::new(); |
63 | let custom_slab = Slab::<u64, _>::new_with_config::<CustomConfig>(); |
64 | |
65 | for i in 0..=ITERS { |
66 | let idx = default_slab.insert(i).unwrap(); |
67 | assert!(default_slab.get(idx).is_some()); |
68 | assert!(default_slab.get(idx).is_some()); |
69 | assert!(default_slab.remove(idx)); |
70 | |
71 | let idx = custom_slab.insert(i).unwrap(); |
72 | assert!(custom_slab.get(idx).is_some()); |
73 | assert!(custom_slab.get(idx).is_some()); |
74 | assert!(custom_slab.remove(idx)); |
75 | } |
76 | |
77 | slab_eq(custom_slab, default_slab); |
78 | } |
79 | |