From 2966b628fa4c9d8cdde99613acdeeb21f2329578 Mon Sep 17 00:00:00 2001 From: Szymon Walter Date: Tue, 20 Mar 2018 10:30:40 +0100 Subject: [PATCH] rewrite how block addresses are constructed --- src/block.rs | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/block.rs b/src/block.rs index 7d267d5..5423631 100644 --- a/src/block.rs +++ b/src/block.rs @@ -42,9 +42,7 @@ pub struct Address { } impl Address { - pub fn new(block: usize, offset: usize) -> Address { - let block = block + (offset >> (S::LOG_SIZE + 10)); - let offset = offset & S::OFFSET_MASK; + pub unsafe fn new_unchecked(block: usize, offset: usize) -> Address { let _phantom = PhantomData; Address { block, @@ -53,6 +51,12 @@ impl Address { } } + pub fn new(block: usize, offset: isize) -> Address { + let block = (block as isize + (offset >> (S::LOG_SIZE + 10))) as usize; + let offset = offset.abs() as usize & S::OFFSET_MASK; + unsafe { Address::new_unchecked(block, offset) } + } + pub fn into_index(&self) -> Option { self.block .checked_shl(S::LOG_SIZE + 10) @@ -102,29 +106,27 @@ impl From for Address { fn from(idx: usize) -> Address { let block = idx >> (S::LOG_SIZE + 10); let offset = idx & S::OFFSET_MASK; - Address::new(block, offset) + Address::new(block, offset as isize) } } impl Add for Address { type Output = Address; fn add(self, rhs: Address) -> Address { - let offset = self.offset + rhs.offset; - let block = offset >> (S::LOG_SIZE + 10); - let offset = offset & S::OFFSET_MASK; - Address::new(self.block + rhs.block + block, offset) + Address::new( + self.block + rhs.block, + (self.offset + rhs.offset) as isize, + ) } } impl Sub for Address { type Output = Address; - fn sub(mut self, rhs: Address) -> Address { - if rhs.offset > self.offset { - self.offset += S::SIZE; - self.block -= 1; - } - let offset = self.offset - rhs.offset; - Address::new(self.block - rhs.block, offset) + fn sub(self, rhs: Address) -> Address { + Address::new( + self.block + rhs.block, + self.offset as isize - rhs.offset as isize, + ) } } @@ -139,6 +141,11 @@ mod tests { Address::::new(1, 0), ); + assert_eq!( + Address::::new(2, -512), + Address::::new(1, 512), + ); + let a = Address::::new(0, 1024); let b = Address::::new(0, 1024); assert_eq!(a + b, Address::::new(1, 0));