- let undef_mask = self.get(src.alloc_id)?.undef_mask.clone();
- let get = |i| undef_mask.get(src.offset + Size::from_bytes(i));
- let dest_allocation = self.get_mut(dest.alloc_id)?;
+ let undef_mask = &self.get(src.alloc_id)?.undef_mask;
+
+ // a precomputed cache for ranges of defined/undefined bits
+ // 0000010010001110 will become
+ // [5, 1, 2, 1, 3, 3, 1]
+ // where each element toggles the state
+ let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
+ let first = undef_mask.get(src.offset);
+ let mut cur_len = 1;
+ let mut cur = first;
+ for i in 1..size.bytes() {
+ // FIXME: optimize to bitshift the current undef block's bits and read the top bit
+ if undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
+ cur_len += 1;
+ } else {
+ ranges.push(cur_len);
+ cur_len = 1;
+ cur = !cur;
+ }
+ }