#![allow(dead_code)]
use super::consts::*;
#[inline]
pub fn calculate_msb(value: usize) -> Option<usize> {
if value == 0 {
None
} else {
let offset = {
let mut offset = 0;
let mut value = value;
while value > 0xFF {
offset += 8;
value >>= 8;
}
offset
};
Some(INDEX_TABLE[value >> offset] as usize + offset)
}
}
#[inline]
pub fn calculate_lsb(value: usize) -> Option<usize> {
let value = value & (!value).overflowing_add(1).0;
let offset = {
let mut value = value;
let mut offset = 0;
while value > 0xFF {
offset += 8;
value >>= 8;
}
offset
};
Some(INDEX_TABLE[value >> offset] as usize + offset)
}
pub fn calculate_mapping_indices(block_size: usize) -> (usize, usize) {
if block_size < SMALL_BLOCK_SIZE {
const FRAGMENT: usize = SMALL_BLOCK_SIZE / SECOND_INDEX_MAX;
(0, block_size / FRAGMENT)
} else {
let first = calculate_msb(block_size).unwrap();
let second = (block_size >> (first - SECOND_INDEX_LOG2_MAX)) - SECOND_INDEX_MAX;
(first - FIRST_INDEX_OFFSET, second)
}
}
#[inline(always)]
pub fn calculate_allocation_size(size: usize) -> usize {
round_up_block(std::cmp::max(size, MINIMUM_BLOCK_SIZE))
}
pub fn calculate_allocation_searching_size(size: usize) -> usize {
let mut size = calculate_allocation_size(size);
if size < SMALL_BLOCK_SIZE {
size
} else {
let t = (1 << (calculate_msb(size).unwrap() - SECOND_INDEX_LOG2_MAX)) - 1;
size += t;
size &= !t;
size
}
}
#[inline(always)]
pub const fn round_up_block(value: usize) -> usize {
const MASK: usize = BLOCK_ALIGNOF - 1;
(value + MASK) & !MASK
}
#[inline(always)]
pub const fn round_down_block(value: usize) -> usize {
const MASK: usize = BLOCK_ALIGNOF - 1;
value & !MASK
}
#[inline(always)]
pub const fn is_aligned(value: usize) -> bool {
(value & (BLOCK_ALIGNOF - 1)) == 0
}
#[inline(always)]
pub const fn calculate_index(mapping_indices: (usize, usize)) -> usize {
let (first, second) = mapping_indices;
first * SECOND_INDEX_MAX + second
}
#[inline(always)]
pub const fn gigabytes_of(size: usize) -> usize {
size * 1024 * 1024 * 1024
}
#[inline(always)]
pub const fn megabytes_of(size: usize) -> usize {
size * 1024 * 1024
}
#[inline(always)]
pub const fn kilobytes_of(size: usize) -> usize {
size * 1024
}
pub fn next_chunk_size(total: usize, last_chunk_size: usize, size: usize) -> usize {
const INIT_CHUNK_SIZE: usize = megabytes_of(2);
const INIT_EXPANDED_ALIGNMENT: usize = megabytes_of(8);
let aligned_size = match size {
s if size > 0 => 0x01 << (calculate_msb(s).unwrap() + 1),
_ => 1024,
};
if total == 0 {
if aligned_size <= (INIT_CHUNK_SIZE >> 2) {
INIT_CHUNK_SIZE
} else {
const ALIGNMENT_MIN1: usize = INIT_EXPANDED_ALIGNMENT - 1;
(aligned_size * 4usize + ALIGNMENT_MIN1) & !ALIGNMENT_MIN1
}
} else {
let expected = last_chunk_size << 1;
if aligned_size * 4usize <= expected {
expected
} else {
let min1 = last_chunk_size - 1;
(aligned_size * 4usize + min1) & !min1
}
}
}