use alloc::vec::Vec;
use core::fmt::Debug;
use core::ops::{Deref, DerefMut};
use crate::arch::u32_to_usize;
use crate::celled::Celled;
use crate::dev::Device;
use crate::dev::address::Address;
pub struct Bitmap<Dev: Device> {
device: Celled<Dev>,
inner: Vec<u8>,
starting_addr: Address,
length: u64,
}
impl<Dev: Device> Debug for Bitmap<Dev> {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
fmt.debug_struct("Bitmap")
.field("inner", &self.inner)
.field("starting_addr", &self.starting_addr)
.field("length", &self.length)
.finish_non_exhaustive()
}
}
impl<Dev: Device> Bitmap<Dev> {
pub fn new(celled_device: Celled<Dev>, starting_addr: Address, length: u64) -> deku::no_std_io::Result<Self> {
let inner = celled_device.lock().slice(starting_addr..(starting_addr + length))?.to_vec();
Ok(Self {
device: celled_device,
inner,
starting_addr,
length,
})
}
#[must_use]
pub const fn length(&self) -> u64 {
self.length
}
#[must_use]
pub const fn starting_address(&self) -> Address {
self.starting_addr
}
pub fn write_back(&mut self) -> deku::no_std_io::Result<()> {
let mut device = self.device.lock();
let mut slice = device.slice(self.starting_addr..(self.starting_addr + self.length))?;
slice.clone_from_slice(&self.inner);
let commit = slice.commit();
device.commit(commit)?;
Ok(())
}
pub fn find_to_count<F: Fn(&u8) -> usize>(&self, n: usize, count: F) -> Vec<(usize, u8)> {
let mut counter = 0_usize;
let mut element_taken = Vec::new();
for (index, element) in self.inner.iter().enumerate() {
let element_count = count(element);
if element_count > 0 {
counter += element_count;
element_taken.push((index, *element));
if counter >= n {
return element_taken;
}
}
}
element_taken
}
#[must_use]
pub fn find_n_set_bits(&self, n: usize) -> Vec<(usize, u8)> {
self.find_to_count(n, |byte| {
let mut count = byte - ((byte >> 1_u8) & 0x55);
count = (count & 0x33) + ((count >> 2_u8) & 0x33);
count = (count + (count >> 4_u8)) & 0x0F;
u32_to_usize(count.into())
})
}
#[must_use]
pub fn find_n_unset_bits(&self, n: usize) -> Vec<(usize, u8)> {
self.find_to_count(n, |byte| {
let mut count = byte - ((byte >> 1_u8) & 0x55);
count = (count & 0x33) + ((count >> 2_u8) & 0x33);
count = (count + (count >> 4_u8)) & 0x0F;
u32_to_usize(8_u32 - Into::<u32>::into(count))
})
}
}
impl<Dev: Device> IntoIterator for Bitmap<Dev> {
type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
type Item = u8;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<Dev: Device> Deref for Bitmap<Dev> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<Dev: Device> DerefMut for Bitmap<Dev> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}