Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@
- Fixed a stale doc link referencing the old `bit_vectors` module.
- Removed completed documentation cleanup tasks from `INVENTORY.md`.
- Fixed a typo in `bench/README.md`.
- Added iterators and `to_vec` helpers for inspecting built vectors.
- Split inspection tests so each assertion stands alone.
1 change: 0 additions & 1 deletion INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
- None at the moment.

## Desired Functionality
- Expose utilities for inspecting and debugging built vectors.
- Provide more usage examples and documentation.
- Evaluate additional succinct data structures to include.
- Investigate alternative dense-select index strategies to replace removed `DArrayIndex`.
Expand Down
56 changes: 56 additions & 0 deletions src/bit_vector/bit_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,37 @@ pub struct BitVector<I> {
pub index: I,
}

/// Iterator over bits in a [`BitVector`].
pub struct Iter<'a, I> {
bv: &'a BitVector<I>,
pos: usize,
}

impl<'a, I> Iter<'a, I> {
/// Creates a new iterator.
pub const fn new(bv: &'a BitVector<I>) -> Self {
Self { bv, pos: 0 }
}
}

impl<I> Iterator for Iter<'_, I> {
type Item = bool;

fn next(&mut self) -> Option<Self::Item> {
if self.pos < self.bv.len() {
let bit = self.bv.access(self.pos).unwrap();
self.pos += 1;
Some(bit)
} else {
None
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
(self.bv.len(), Some(self.bv.len()))
}
}

impl<I> BitVector<I> {
/// Creates a new wrapper from data and index.
pub const fn new(data: BitVectorData, index: I) -> Self {
Expand All @@ -337,6 +368,16 @@ impl<I> BitVector<I> {
pub fn get_bits(&self, pos: usize, len: usize) -> Option<usize> {
self.data.get_bits(pos, len)
}

/// Creates an iterator over all bits.
pub const fn iter(&self) -> Iter<I> {
Iter { bv: self, pos: 0 }
}

/// Collects all bits into a `Vec<bool>` for inspection.
pub fn to_vec(&self) -> Vec<bool> {
self.iter().collect()
}
}

impl<I: BitVectorIndex> NumBits for BitVector<I> {
Expand Down Expand Up @@ -433,4 +474,19 @@ mod tests {
let bv: BitVector<NoIndex> = builder.freeze::<NoIndex>();
assert_eq!(bv.data.get_bits(61, 7).unwrap(), 0b0111110);
}

#[test]
fn iter_collects() {
let data = BitVectorData::from_bits([true, false, true]);
let bv = BitVector::new(data, NoIndex);
let collected: Vec<bool> = bv.iter().collect();
assert_eq!(collected, vec![true, false, true]);
}

#[test]
fn to_vec_collects() {
let data = BitVectorData::from_bits([true, false, true]);
let bv = BitVector::new(data, NoIndex);
assert_eq!(bv.to_vec(), vec![true, false, true]);
}
}
18 changes: 18 additions & 0 deletions src/int_vectors/compact_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ impl CompactVector {
Iter::new(self)
}

/// Collects all integers into a `Vec<usize>` for inspection.
pub fn to_vec(&self) -> Vec<usize> {
self.iter().collect()
}

/// Gets the number of integers.
#[inline(always)]
pub const fn len(&self) -> usize {
Expand Down Expand Up @@ -645,4 +650,17 @@ mod tests {
let cv = CompactVector::from_int(42, 1, 64).unwrap();
assert_eq!(cv.get_int(0), Some(42));
}

#[test]
fn iter_collects() {
let cv = CompactVector::from_slice(&[1, 2, 3]).unwrap();
let collected: Vec<usize> = cv.iter().collect();
assert_eq!(collected, vec![1, 2, 3]);
}

#[test]
fn to_vec_collects() {
let cv = CompactVector::from_slice(&[1, 2, 3]).unwrap();
assert_eq!(cv.to_vec(), vec![1, 2, 3]);
}
}
30 changes: 29 additions & 1 deletion src/int_vectors/dacs_byte.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const LEVEL_MASK: usize = (1 << LEVEL_WIDTH) - 1;
///
/// - N. R. Brisaboa, S. Ladra, and G. Navarro, "DACs: Bringing direct access to variable-length
/// codes." Information Processing & Management, 49(1), 392-404, 2013.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq)]
pub struct DacsByte {
data: Vec<View<[u8]>>,
flags: Vec<BitVector<Rank9SelIndex>>,
Expand Down Expand Up @@ -151,6 +151,11 @@ impl DacsByte {
Iter::new(self)
}

/// Collects all integers into a `Vec<usize>` for inspection.
pub fn to_vec(&self) -> Vec<usize> {
self.iter().collect()
}

/// Gets the number of integers.
#[inline(always)]
pub fn len(&self) -> usize {
Expand Down Expand Up @@ -260,6 +265,16 @@ impl<'a> Iter<'a> {
}
}

impl std::fmt::Debug for DacsByte {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DacsByte")
.field("ints", &self.to_vec())
.field("len", &self.len())
.field("num_levels", &self.num_levels())
.finish()
}
}

impl Iterator for Iter<'_> {
type Item = usize;

Expand Down Expand Up @@ -360,6 +375,19 @@ mod tests {
assert_eq!(seq.access(3), Some(0));
}

#[test]
fn iter_collects() {
let seq = DacsByte::from_slice(&[5, 7]).unwrap();
let collected: Vec<usize> = seq.iter().collect();
assert_eq!(collected, vec![5, 7]);
}

#[test]
fn to_vec_collects() {
let seq = DacsByte::from_slice(&[5, 7]).unwrap();
assert_eq!(seq.to_vec(), vec![5, 7]);
}

#[test]
fn test_from_slice_uncastable() {
let e = DacsByte::from_slice(&[u128::MAX]);
Expand Down