refactor: replace byte-level bit iteration with 64-bit words
Refactor `BitIter` to process `u64` chunks using word-aligned shifts instead of byte-level operations. Introduce a dedicated `MemoryBitIter` for `MemoryBitVec`, updating its `iter()` and `IntoIterator` implementations accordingly. Hide `MemoryBitIter` from the public API to narrow the crate's interface, while leveraging explicit alignment guarantees for safer and more efficient bit extraction.
This commit is contained in:
@@ -65,12 +65,7 @@ impl PersistentBitVec {
|
||||
(self.mmap[HEADER_SIZE + (slot >> 3)] >> (slot & 7)) & 1 != 0
|
||||
}
|
||||
|
||||
// Used by iter() and get(): exact byte window, no padding.
|
||||
fn data_bytes(&self) -> &[u8] {
|
||||
&self.mmap[HEADER_SIZE..HEADER_SIZE + self.n.div_ceil(8)]
|
||||
}
|
||||
|
||||
// Bulk word view. SAFETY: mmap is page-aligned, HEADER_SIZE=16 is divisible by 8,
|
||||
// SAFETY: mmap is page-aligned, HEADER_SIZE=16 is divisible by 8,
|
||||
// so &mmap[HEADER_SIZE] is u64-aligned. Slice length is n_words * 8 bytes.
|
||||
fn data_words(&self) -> &[u64] {
|
||||
let nw = n_words(self.n);
|
||||
@@ -79,11 +74,7 @@ impl PersistentBitVec {
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> BitIter<'_> {
|
||||
BitIter {
|
||||
bytes: self.data_bytes(),
|
||||
slot: 0,
|
||||
n: self.n,
|
||||
}
|
||||
BitIter { words: self.data_words(), slot: 0, n: self.n }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,9 +87,9 @@ impl<'a> IntoIterator for &'a PersistentBitVec {
|
||||
}
|
||||
|
||||
pub struct BitIter<'a> {
|
||||
bytes: &'a [u8],
|
||||
slot: usize,
|
||||
n: usize,
|
||||
pub(crate) words: &'a [u64],
|
||||
pub(crate) slot: usize,
|
||||
pub(crate) n: usize,
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for BitIter<'_> {}
|
||||
@@ -107,10 +98,8 @@ impl Iterator for BitIter<'_> {
|
||||
type Item = bool;
|
||||
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
if self.slot >= self.n {
|
||||
return None;
|
||||
}
|
||||
let v = (self.bytes[self.slot >> 3] >> (self.slot & 7)) & 1 != 0;
|
||||
if self.slot >= self.n { return None; }
|
||||
let v = (self.words[self.slot >> 6] >> (self.slot & 63)) & 1 != 0;
|
||||
self.slot += 1;
|
||||
Some(v)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ pub use builder::PersistentCompactIntVecBuilder;
|
||||
pub use intmatrix::{PersistentCompactIntMatrix, PersistentCompactIntMatrixBuilder, pack_compact_int_matrix};
|
||||
pub use layer_meta::LayerMeta;
|
||||
pub use memoryintvec::{MemoryIntIter, MemoryIntVec};
|
||||
pub use memoryvec::{MemoryBitIter, MemoryBitVec};
|
||||
pub use memoryvec::MemoryBitVec;
|
||||
pub use reader::PersistentCompactIntVec;
|
||||
pub use traits::{BitPartials, BitSlice, BitSliceMut, BitToInt, ColumnWeights, CountPartials, IntSlice, IntSliceMut, IntToBit};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::io;
|
||||
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::bitvec::{PersistentBitVecBuilder, n_words};
|
||||
use crate::bitvec::{BitIter, PersistentBitVecBuilder, n_words};
|
||||
use crate::traits::{BitSlice, BitSliceMut};
|
||||
|
||||
// ── MemoryBitVec ──────────────────────────────────────────────────────────────
|
||||
@@ -125,38 +125,14 @@ impl<B: BitSlice> BitXorAssign<&B> for MemoryBitVec {
|
||||
|
||||
// ── Iterator ──────────────────────────────────────────────────────────────────
|
||||
|
||||
pub struct MemoryBitIter<'a> {
|
||||
words: &'a [u64],
|
||||
slot: usize,
|
||||
n: usize,
|
||||
}
|
||||
|
||||
impl Iterator for MemoryBitIter<'_> {
|
||||
type Item = bool;
|
||||
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
if self.slot >= self.n { return None; }
|
||||
let v = (self.words[self.slot >> 6] >> (self.slot & 63)) & 1 != 0;
|
||||
self.slot += 1;
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let rem = self.n - self.slot;
|
||||
(rem, Some(rem))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for MemoryBitIter<'_> {}
|
||||
|
||||
impl MemoryBitVec {
|
||||
pub fn iter(&self) -> MemoryBitIter<'_> {
|
||||
MemoryBitIter { words: &self.words, slot: 0, n: self.n }
|
||||
pub fn iter(&self) -> BitIter<'_> {
|
||||
BitIter { words: &self.words, slot: 0, n: self.n }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a MemoryBitVec {
|
||||
type Item = bool;
|
||||
type IntoIter = MemoryBitIter<'a>;
|
||||
fn into_iter(self) -> MemoryBitIter<'a> { self.iter() }
|
||||
type IntoIter = BitIter<'a>;
|
||||
fn into_iter(self) -> BitIter<'a> { self.iter() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user