use core::alloc::Layout;
pub const SIZE_CLASS_COUNT: usize = 9;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum SizeClass {
Bytes8 = 0,
Bytes16 = 1,
Bytes32 = 2,
Bytes64 = 3,
Bytes128 = 4,
Bytes256 = 5,
Bytes512 = 6,
Bytes1024 = 7,
Bytes2048 = 8,
}
pub const SLAB_MAX_SIZE: usize = 2048;
const CLASS_SIZES: [usize; SIZE_CLASS_COUNT] = [8, 16, 32, 64, 128, 256, 512, 1024, 2048];
impl SizeClass {
pub const ALL: [SizeClass; SIZE_CLASS_COUNT] = [
SizeClass::Bytes8,
SizeClass::Bytes16,
SizeClass::Bytes32,
SizeClass::Bytes64,
SizeClass::Bytes128,
SizeClass::Bytes256,
SizeClass::Bytes512,
SizeClass::Bytes1024,
SizeClass::Bytes2048,
];
pub const COUNT: usize = SIZE_CLASS_COUNT;
pub fn from_layout(layout: Layout) -> Option<SizeClass> {
let size = layout.size().max(layout.align());
if size > SLAB_MAX_SIZE {
return None;
}
for (i, &class_size) in CLASS_SIZES.iter().enumerate() {
if size <= class_size {
return Some(SizeClass::ALL[i]);
}
}
None
}
pub const fn size(self) -> usize {
CLASS_SIZES[self as usize]
}
pub const fn index(self) -> usize {
self as usize
}
pub const fn slab_pages(self, page_size: usize) -> usize {
let obj_size = self.size();
if obj_size <= 256 {
1
} else if obj_size <= 1024 {
2
} else {
let v = 16 * page_size / (obj_size * 8);
let v = if v < 4 { v } else { 4 };
if v < 1 { 1 } else { v }
}
}
}