1 2 3 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 74 75 76 77 78 79
use num_traits::{Unsigned, NumCast, PrimInt, Num}; use std::iter::{FusedIterator, Iterator}; use std::marker::PhantomData; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct MemoryPortsReadWrittenIterator<'m, IdxT: Num + Unsigned + PrimInt + NumCast> { data: &'m [u8], read: &'m [u64], written: &'m [u64], next_idx: usize, finished: bool, idx: PhantomData<IdxT>, } impl<'m, IdxT: Num + Unsigned + PrimInt + NumCast> MemoryPortsReadWrittenIterator<'m, IdxT> { #[cfg_attr(rustfmt, rustfmt_skip)] pub(super) fn new(data: &'m [u8], read: &'m [u64], written: &'m [u64]) -> MemoryPortsReadWrittenIterator<'m, IdxT> { MemoryPortsReadWrittenIterator { data: data, read: read, written: written, next_idx: 0, finished: false, idx: PhantomData, } } } impl<IdxT: Num + Unsigned + PrimInt + NumCast> Iterator for MemoryPortsReadWrittenIterator<'_, IdxT> { type Item = (IdxT, u8, bool, bool); fn next(&mut self) -> Option<Self::Item> { next(self.data, self.read, self.written, &mut self.next_idx, &mut self.finished).map(|(idx, dt, wr, ww)| (IdxT::from(idx).unwrap(), dt, wr, ww)) } } impl<IdxT: Num + Unsigned + PrimInt + NumCast> FusedIterator for MemoryPortsReadWrittenIterator<'_, IdxT> {} fn next(self_data: &[u8], self_read: &[u64], self_written: &[u64], next_idx: &mut usize, self_finished: &mut bool) -> Option<(usize, u8, bool, bool)> { if *self_finished { return None; } let (was_read, was_written) = loop { if *next_idx >= self_data.len() { *self_finished = true; return None; } let idx = *next_idx / 64; let bit = *next_idx % 64; let read = self_read[idx]; let written = self_written[idx]; if read == 0 && written == 0 { *next_idx += 64 - bit; continue; } let mask = 1 << bit; let was_read = (read & mask) != 0; let was_written = (written & mask) != 0; if !was_read && !was_written { *next_idx += 1; continue; } break (was_read, was_written); }; let idx = *next_idx; *next_idx += 1; Some((idx, self_data[idx], was_read, was_written)) }