use std::fmt::{self, Debug};
use std::ops::Deref;
use std::sync::Arc;
use crate::bitmap::{Bitmap, BitmapSlice, WithBitmapSlice};
#[derive(Clone, Copy)]
pub struct BaseSlice<B> {
inner: B,
base_offset: usize,
}
impl<B> BaseSlice<B> {
pub fn new(inner: B, offset: usize) -> Self {
BaseSlice {
inner,
base_offset: offset,
}
}
}
impl<'a, B> WithBitmapSlice<'a> for BaseSlice<B>
where
B: Clone + Deref,
B::Target: Bitmap,
{
type S = Self;
}
impl<B> BitmapSlice for BaseSlice<B>
where
B: Clone + Deref,
B::Target: Bitmap,
{
}
impl<B> Bitmap for BaseSlice<B>
where
B: Clone + Deref,
B::Target: Bitmap,
{
fn mark_dirty(&self, offset: usize, len: usize) {
self.inner
.mark_dirty(self.base_offset.wrapping_add(offset), len)
}
fn dirty_at(&self, offset: usize) -> bool {
self.inner.dirty_at(self.base_offset.wrapping_add(offset))
}
fn slice_at(&self, offset: usize) -> Self {
BaseSlice {
inner: self.inner.clone(),
base_offset: self.base_offset.wrapping_add(offset),
}
}
}
impl<B> Debug for BaseSlice<B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(bitmap slice)")
}
}
impl<B: Default> Default for BaseSlice<B> {
fn default() -> Self {
BaseSlice {
inner: B::default(),
base_offset: 0,
}
}
}
pub type RefSlice<'a, B> = BaseSlice<&'a B>;
pub type ArcSlice<B> = BaseSlice<Arc<B>>;
#[cfg(test)]
mod tests {
use super::*;
use crate::bitmap::tests::{range_is_clean, range_is_dirty, test_bitmap};
use crate::bitmap::AtomicBitmap;
#[test]
fn test_slice() {
let bitmap_size = 0x1_0000;
let dirty_offset = 0x1000;
let dirty_len = 0x100;
{
let bitmap = AtomicBitmap::new(bitmap_size, 1);
let slice1 = bitmap.slice_at(0);
let slice2 = bitmap.slice_at(dirty_offset);
assert!(range_is_clean(&slice1, 0, bitmap_size));
assert!(range_is_clean(&slice2, 0, dirty_len));
bitmap.mark_dirty(dirty_offset, dirty_len);
assert!(range_is_dirty(&slice1, dirty_offset, dirty_len));
assert!(range_is_dirty(&slice2, 0, dirty_len));
}
{
let bitmap = AtomicBitmap::new(bitmap_size, 1);
let slice = bitmap.slice_at(0);
test_bitmap(&slice);
}
}
}