use crate::allocators::allocator::Allocator;
use crate::allocators::bit_set::bit_set_allocator::BitSetAllocator;
use crate::allocators::bump_allocator::BumpAllocator;
use crate::allocators::global::local_allocator::LocalAllocator;
use crate::allocators::global::memory_range::MemoryRange;
use crate::allocators::multiple_binary_search_tree_allocator::MultipleBinarySearchTreeAllocator;
use crate::memory_address::MemoryAddress;
use crate::memory_sources::memory_source::MemorySource;
use std::alloc::AllocErr;
use std::fmt::Debug;
use std::num::NonZeroUsize;
#[derive(Debug)]
pub enum ContextAllocator<MS: MemorySource> {
ShortLived(BumpAllocator<MS>),
MediumLived(BitSetAllocator<MS>),
LongLived(MultipleBinarySearchTreeAllocator<MS>),
}
impl<MS: MemorySource> Allocator for ContextAllocator<MS> {
#[inline(always)]
fn allocate(
&self,
non_zero_size: NonZeroUsize,
non_zero_power_of_two_alignment: NonZeroUsize,
) -> Result<MemoryAddress, AllocErr> {
use self::ContextAllocator::*;
match *self {
ShortLived(ref allocator) => {
allocator.allocate(non_zero_size, non_zero_power_of_two_alignment)
}
MediumLived(ref allocator) => {
allocator.allocate(non_zero_size, non_zero_power_of_two_alignment)
}
LongLived(ref allocator) => {
allocator.allocate(non_zero_size, non_zero_power_of_two_alignment)
}
}
}
#[inline(always)]
fn deallocate(
&self,
non_zero_size: NonZeroUsize,
non_zero_power_of_two_alignment: NonZeroUsize,
current_memory: MemoryAddress,
) {
use self::ContextAllocator::*;
match *self {
ShortLived(ref allocator) => allocator.deallocate(
non_zero_size,
non_zero_power_of_two_alignment,
current_memory,
),
MediumLived(ref allocator) => allocator.deallocate(
non_zero_size,
non_zero_power_of_two_alignment,
current_memory,
),
LongLived(ref allocator) => allocator.deallocate(
non_zero_size,
non_zero_power_of_two_alignment,
current_memory,
),
}
}
#[inline(always)]
fn growing_reallocate(
&self,
non_zero_new_size: NonZeroUsize,
non_zero_power_of_two_alignment: NonZeroUsize,
non_zero_current_size: NonZeroUsize,
current_memory: MemoryAddress,
) -> Result<MemoryAddress, AllocErr> {
use self::ContextAllocator::*;
match *self {
ShortLived(ref allocator) => allocator.growing_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
MediumLived(ref allocator) => allocator.growing_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
LongLived(ref allocator) => allocator.growing_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
}
}
#[inline(always)]
fn shrinking_reallocate(
&self,
non_zero_new_size: NonZeroUsize,
non_zero_power_of_two_alignment: NonZeroUsize,
non_zero_current_size: NonZeroUsize,
current_memory: MemoryAddress,
) -> Result<MemoryAddress, AllocErr> {
use self::ContextAllocator::*;
match *self {
ShortLived(ref allocator) => allocator.shrinking_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
MediumLived(ref allocator) => allocator.shrinking_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
LongLived(ref allocator) => allocator.shrinking_reallocate(
non_zero_new_size,
non_zero_power_of_two_alignment,
non_zero_current_size,
current_memory,
),
}
}
}
impl<MS: MemorySource> LocalAllocator for ContextAllocator<MS> {
#[inline(always)]
fn memory_range(&self) -> MemoryRange {
use self::ContextAllocator::*;
match *self {
ShortLived(ref allocator) => allocator.memory_range(),
MediumLived(ref allocator) => allocator.memory_range(),
LongLived(ref allocator) => allocator.memory_range(),
}
}
}