vm_memory/bitmap/backend/
slice.rs1use std::fmt::{self, Debug};
7use std::ops::Deref;
8use std::sync::Arc;
9
10use crate::bitmap::{Bitmap, BitmapSlice, WithBitmapSlice};
11
12#[derive(Clone, Copy)]
14pub struct BaseSlice<B> {
15 inner: B,
16 base_offset: usize,
17}
18
19impl<B> BaseSlice<B> {
20 pub fn new(inner: B, offset: usize) -> Self {
22 BaseSlice {
23 inner,
24 base_offset: offset,
25 }
26 }
27}
28
29impl<B> WithBitmapSlice<'_> for BaseSlice<B>
30where
31 B: Clone + Deref,
32 B::Target: Bitmap,
33{
34 type S = Self;
35}
36
37impl<B> BitmapSlice for BaseSlice<B>
38where
39 B: Clone + Deref,
40 B::Target: Bitmap,
41{
42}
43
44impl<B> Bitmap for BaseSlice<B>
45where
46 B: Clone + Deref,
47 B::Target: Bitmap,
48{
49 fn mark_dirty(&self, offset: usize, len: usize) {
52 self.inner
58 .mark_dirty(self.base_offset.wrapping_add(offset), len)
59 }
60
61 fn dirty_at(&self, offset: usize) -> bool {
62 self.inner.dirty_at(self.base_offset.wrapping_add(offset))
63 }
64
65 fn slice_at(&self, offset: usize) -> Self {
67 BaseSlice {
68 inner: self.inner.clone(),
69 base_offset: self.base_offset.wrapping_add(offset),
70 }
71 }
72}
73
74impl<B> Debug for BaseSlice<B> {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(f, "(bitmap slice)")
78 }
79}
80
81impl<B: Default> Default for BaseSlice<B> {
82 fn default() -> Self {
83 BaseSlice {
84 inner: B::default(),
85 base_offset: 0,
86 }
87 }
88}
89
90pub type RefSlice<'a, B> = BaseSlice<&'a B>;
92
93pub type ArcSlice<B> = BaseSlice<Arc<B>>;
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 use crate::bitmap::tests::{range_is_clean, range_is_dirty, test_bitmap};
101 use crate::bitmap::AtomicBitmap;
102 use std::num::NonZeroUsize;
103
104 #[test]
105 fn test_slice() {
106 let bitmap_size = 0x800;
107 let dirty_offset = 0x400;
108 let dirty_len = 0x100;
109
110 {
111 let bitmap = AtomicBitmap::new(bitmap_size, NonZeroUsize::MIN);
112 let slice1 = bitmap.slice_at(0);
113 let slice2 = bitmap.slice_at(dirty_offset);
114
115 assert!(range_is_clean(&slice1, 0, bitmap_size));
116 assert!(range_is_clean(&slice2, 0, dirty_len));
117
118 bitmap.mark_dirty(dirty_offset, dirty_len);
119
120 assert!(range_is_dirty(&slice1, dirty_offset, dirty_len));
121 assert!(range_is_dirty(&slice2, 0, dirty_len));
122 }
123
124 {
125 let bitmap = AtomicBitmap::new(bitmap_size, NonZeroUsize::MIN);
126 let slice = bitmap.slice_at(0);
127 test_bitmap(&slice);
128 }
129 }
130}