1 // Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause 3 4 use std::ops::Deref; 5 use std::sync::Arc; 6 7 use crate::bitmap::{ArcSlice, AtomicBitmap, Bitmap, WithBitmapSlice}; 8 9 #[cfg(feature = "backend-mmap")] 10 use crate::mmap::NewBitmap; 11 12 /// A `Bitmap` implementation that's based on an atomically reference counted handle to an 13 /// `AtomicBitmap` object. 14 pub struct AtomicBitmapArc { 15 inner: Arc<AtomicBitmap>, 16 } 17 18 impl AtomicBitmapArc { new(inner: AtomicBitmap) -> Self19 pub fn new(inner: AtomicBitmap) -> Self { 20 AtomicBitmapArc { 21 inner: Arc::new(inner), 22 } 23 } 24 } 25 26 // The current clone implementation creates a deep clone of the inner bitmap, as opposed to 27 // simply cloning the `Arc`. 28 impl Clone for AtomicBitmapArc { clone(&self) -> Self29 fn clone(&self) -> Self { 30 Self::new(self.inner.deref().clone()) 31 } 32 } 33 34 // Providing a `Deref` to `AtomicBitmap` implementation, so the methods of the inner object 35 // can be called in a transparent manner. 36 impl Deref for AtomicBitmapArc { 37 type Target = AtomicBitmap; 38 deref(&self) -> &Self::Target39 fn deref(&self) -> &Self::Target { 40 self.inner.deref() 41 } 42 } 43 44 impl WithBitmapSlice<'_> for AtomicBitmapArc { 45 type S = ArcSlice<AtomicBitmap>; 46 } 47 48 impl Bitmap for AtomicBitmapArc { mark_dirty(&self, offset: usize, len: usize)49 fn mark_dirty(&self, offset: usize, len: usize) { 50 self.inner.set_addr_range(offset, len) 51 } 52 dirty_at(&self, offset: usize) -> bool53 fn dirty_at(&self, offset: usize) -> bool { 54 self.inner.is_addr_set(offset) 55 } 56 slice_at(&self, offset: usize) -> <Self as WithBitmapSlice>::S57 fn slice_at(&self, offset: usize) -> <Self as WithBitmapSlice>::S { 58 ArcSlice::new(self.inner.clone(), offset) 59 } 60 } 61 62 impl Default for AtomicBitmapArc { default() -> Self63 fn default() -> Self { 64 Self::new(AtomicBitmap::default()) 65 } 66 } 67 68 #[cfg(feature = "backend-mmap")] 69 impl NewBitmap for AtomicBitmapArc { with_len(len: usize) -> Self70 fn with_len(len: usize) -> Self { 71 Self::new(AtomicBitmap::with_len(len)) 72 } 73 } 74 75 #[cfg(test)] 76 mod tests { 77 use super::*; 78 79 use crate::bitmap::tests::test_bitmap; 80 81 #[test] test_bitmap_impl()82 fn test_bitmap_impl() { 83 let b = AtomicBitmapArc::new(AtomicBitmap::new(0x2000, 128)); 84 test_bitmap(&b); 85 } 86 } 87