address_bitmap.rs 2.19 KB
Newer Older
1 2 3
use utils::LOG_POINTER_SIZE;
use utils::Address;
use common::bitmap::Bitmap;
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

#[derive(Clone)]
pub struct AddressBitmap {
    start : Address,
    end   : Address,
    
    bitmap: Bitmap    
}

impl AddressBitmap {
    pub fn new(start: Address, end: Address) -> AddressBitmap {
        let bitmap_len = end.diff(start) >> LOG_POINTER_SIZE;
        let bitmap = Bitmap::new(bitmap_len);
        
        AddressBitmap{start: start, end: end, bitmap: bitmap}
    }
    
    #[inline(always)]
    #[allow(mutable_transmutes)]
    pub unsafe fn set_bit(&self, addr: Address) {
        use std::mem;
        let mutable_bitmap : &mut Bitmap = mem::transmute(&self.bitmap);
        mutable_bitmap.set_bit(addr.diff(self.start) >> LOG_POINTER_SIZE);
    }
    
    #[inline(always)]
    #[allow(mutable_transmutes)]
    pub unsafe fn clear_bit(&self, addr: Address) {
        use std::mem;
        let mutable_bitmap : &mut Bitmap = mem::transmute(&self.bitmap);        
        mutable_bitmap.clear_bit(addr.diff(self.start) >> LOG_POINTER_SIZE);
    }
    
    #[inline(always)]
    pub fn test_bit(&self, addr: Address) -> bool {
        self.bitmap.test_bit(addr.diff(self.start) >> LOG_POINTER_SIZE)
    }
        
    #[inline(always)]
    pub fn length_until_next_bit(&self, addr: Address) -> usize {
        self.bitmap.length_until_next_bit(addr.diff(self.start) >> LOG_POINTER_SIZE)
    }
    
    #[inline(always)]
    #[allow(mutable_transmutes)]
    pub unsafe fn set(&self, addr: Address, value: u64, length: usize) {
        use std::mem;
        
        if cfg!(debug_assertions) {
            assert!(addr >= self.start && addr <= self.end);
        }
        
        let index = addr.diff(self.start) >> LOG_POINTER_SIZE;
        let mutable_bitmap : &mut Bitmap = mem::transmute(&self.bitmap);
        mutable_bitmap.set(index, value, length);
    }
    
    #[inline(always)]
    pub fn get(&self, addr: Address, length: usize) -> u64 {
        if cfg!(debug_assertions) {
            assert!(addr >= self.start && addr <= self.end);
        }
        
        let index = addr.diff(self.start) >> LOG_POINTER_SIZE;
        self.bitmap.get(index, length)
    }

    pub fn print(&self) {
        self.bitmap.print();
    }
74
}