1use std::{fmt::Debug, marker::PhantomData};
2
3pub trait Config: Sized {
16 const INITIAL_PAGE_SIZE: u32 = DefaultConfig::INITIAL_PAGE_SIZE;
25
26 const MAX_PAGES: u32 = DefaultConfig::MAX_PAGES;
33
34 const RESERVED_BITS: u32 = DefaultConfig::RESERVED_BITS;
43
44 #[must_use]
47 fn debug() -> impl Debug {
48 DebugConfig::<Self>(PhantomData)
49 }
50}
51
52#[allow(missing_debug_implementations)] pub struct DefaultConfig;
58
59impl Config for DefaultConfig {
60 const INITIAL_PAGE_SIZE: u32 = 32;
61 const MAX_PAGES: u32 = 27;
62 const RESERVED_BITS: u32 = 0;
63}
64
65pub(crate) trait ConfigPrivate: Config {
66 const USED_BITS: u32 = 64 - Self::RESERVED_BITS;
67 const SLOT_BITS: u32 = Self::MAX_PAGES + Self::INITIAL_PAGE_SIZE.trailing_zeros();
68 const SLOT_MASK: u32 = ((1u64 << Self::SLOT_BITS) - 1) as u32;
69 const GENERATION_BITS: u32 = Self::USED_BITS - Self::SLOT_BITS;
70 const GENERATION_MASK: u32 = ((1u64 << Self::GENERATION_BITS) - 1) as u32;
71
72 const MAX_SLOTS: u64 = ((1u64 << Self::MAX_PAGES) - 1) * Self::INITIAL_PAGE_SIZE as u64;
74 const MAX_GENERATIONS: u64 = 1u64 << Self::GENERATION_BITS;
75
76 const ENSURE_VALID: bool = {
79 assert!(Self::INITIAL_PAGE_SIZE.is_power_of_two());
80 assert!(Self::MAX_PAGES > 0);
81 assert!(Self::RESERVED_BITS <= 32);
82 assert!(Self::SLOT_BITS <= 32);
83 assert!(Self::GENERATION_BITS <= 32);
84 true
85 };
86}
87
88impl<C: Config> ConfigPrivate for C {}
89
90struct DebugConfig<C>(PhantomData<C>);
91
92impl<C: Config> Debug for DebugConfig<C> {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 f.debug_struct(std::any::type_name::<C>())
95 .field("INITIAL_PAGE_SIZE", &C::INITIAL_PAGE_SIZE)
96 .field("MAX_PAGES", &C::MAX_PAGES)
97 .field("RESERVED_BITS", &C::RESERVED_BITS)
98 .field("USED_BITS", &C::USED_BITS)
99 .field("SLOT_BITS", &C::SLOT_BITS)
100 .field("GENERATION_BITS", &C::GENERATION_BITS)
101 .field("MAX_SLOTS", &C::MAX_SLOTS)
102 .field("MAX_GENERATIONS", &C::MAX_GENERATIONS)
103 .finish()
104 }
105}
106
107#[test]
108fn test_default_config() {
109 assert_eq!(DefaultConfig::USED_BITS, 64);
110 assert_eq!(DefaultConfig::SLOT_BITS, 32);
111 assert_eq!(DefaultConfig::SLOT_MASK, u32::MAX);
112 assert_eq!(DefaultConfig::GENERATION_BITS, 32);
113 assert_eq!(DefaultConfig::GENERATION_MASK, u32::MAX);
114 assert_eq!(DefaultConfig::MAX_SLOTS, 4_294_967_264);
115 assert_eq!(DefaultConfig::MAX_GENERATIONS, 4_294_967_296);
116}