Skip to content
Open
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
23 changes: 22 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ jobs:
run: cargo test --features miniserde --verbose
- name: Run borsh tests
run: cargo test --features borsh --verbose
- name: Run smallvec tests
run: cargo test --features smallvec --verbose
- name: Run smallvec and serde tests
run: cargo test --features smallvec,serde --verbose

miri:
name: "Miri"
Expand Down Expand Up @@ -58,7 +62,7 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [1.85.0, 1.86.0]
rust: [1.86.0, 1.87.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v5
Expand All @@ -67,16 +71,22 @@ jobs:
toolchain: ${{matrix.rust}}
- run: cargo build
- run: cargo build --features serde
- run: cargo build --features serde,smallvec
- run: cargo build --features serde --no-default-features
- run: cargo build --features serde,smallvec --no-default-features
- run: cargo build --features miniserde
- run: cargo build --features borsh
- run: cargo build --features borsh,serde
- run: cargo build --features borsh,serde,miniserde
- run: cargo build --features borsh,serde,miniserde --no-default-features
- run: cargo build --features borsh,serde,miniserde,smallvec --no-default-features
- run: cargo test
- run: cargo test --features serde
- run: cargo test --features serde,smallvec
- run: cargo test --features borsh,serde,miniserde
- run: cargo test --features borsh,serde,miniserde,smallvec
- run: cargo test --features borsh,serde,miniserde --no-default-features
- run: cargo test --features borsh,serde,miniserde,smallvec --no-default-features

clippy:
runs-on: ubuntu-latest
Expand All @@ -90,6 +100,7 @@ jobs:
- run: cargo clippy --workspace --tests --examples --features serde
- run: cargo clippy --workspace --tests --examples --features miniserde
- run: cargo clippy --workspace --tests --examples --features borsh
- run: cargo clippy --workspace --tests --examples --features smallvec

docs:
runs-on: ubuntu-latest
Expand All @@ -102,3 +113,13 @@ jobs:
toolchain: stable
- uses: swatinem/rust-cache@v2
- run: cargo doc --workspace --no-deps

success:
runs-on: ubuntu-latest
needs: [fmt, clippy, miri, msrv]
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- run: echo empty
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"rust-analyzer.check.command": "clippy",
"rust-analyzer.cargo.features": ["serde", "borsh", "miniserde"]
"rust-analyzer.cargo.features": ["serde", "borsh", "miniserde", "smallvec"]
}
2 changes: 1 addition & 1 deletion matrix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name = "bit_matrix"
[dependencies]
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true }
miniserde = { version = "0.1", optional = true }
borsh = { version = "1.7.0", optional = true }
borsh = { version = "1.8.0", optional = true }

[dependencies.bit-vec]
path = "../vec/"
Expand Down
2 changes: 2 additions & 0 deletions matrix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
#![warn(clippy::multiple_crate_versions)]
#![warn(clippy::single_match)]
#![warn(clippy::missing_safety_doc)]
// FIXME https://github.com/near/borsh/issues/159
#![allow(clippy::multiple_crate_versions)]

mod matrix;
mod row;
Expand Down
22 changes: 11 additions & 11 deletions matrix/src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl<B: BitBlock> BitMatrix<B> {
/// Create a new BitMatrix with specific numbers of bits in columns and rows.
pub fn new(rows: usize, row_bits: usize) -> Self {
BitMatrix {
bit_vec: BitVec::from_elem_general(round_up_to_next(row_bits, B::bits()) * rows, false),
bit_vec: BitVec::from_elem_general(round_up_to_next(row_bits, B::BITS) * rows, false),
row_bits,
}
}
Expand All @@ -35,7 +35,7 @@ impl<B: BitBlock> BitMatrix<B> {
if self.row_bits == 0 {
0
} else {
let row_blocks = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_blocks = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
self.bit_vec.storage().len() / row_blocks
}
}
Expand All @@ -58,7 +58,7 @@ impl<B: BitBlock> BitMatrix<B> {
/// Panics if `(row, col)` is out of bounds.
#[inline]
pub fn set(&mut self, row: usize, col: usize, enabled: bool) {
let row_size_in_bits = round_up_to_next(self.row_bits, B::bits());
let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS);
self.bit_vec.set(row * row_size_in_bits + col, enabled);
}

Expand All @@ -71,19 +71,19 @@ impl<B: BitBlock> BitMatrix<B> {
/// Grows the matrix in-place, adding `num_rows` rows filled with `value`.
pub fn grow(&mut self, num_rows: usize, value: bool) {
self.bit_vec
.grow(round_up_to_next(self.row_bits, B::bits()) * num_rows, value);
.grow(round_up_to_next(self.row_bits, B::BITS) * num_rows, value);
}

/// Truncates the matrix.
pub fn truncate(&mut self, num_rows: usize) {
self.bit_vec
.truncate(round_up_to_next(self.row_bits, B::bits()) * num_rows);
.truncate(round_up_to_next(self.row_bits, B::BITS) * num_rows);
}

/// Returns a slice of the matrix's rows.
#[inline]
pub fn sub_matrix<R: RangeBounds<usize>>(&self, range: R) -> BitSubMatrix<'_, B> {
let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
BitSubMatrix {
slice: &self.bit_vec.storage()[(
range.start_bound().map(|&s| s * row_size),
Expand Down Expand Up @@ -111,7 +111,7 @@ impl<B: BitBlock> BitMatrix<B> {
}

fn row_size(&self) -> usize {
round_up_to_next(self.row_bits, B::bits()) / B::bits()
round_up_to_next(self.row_bits, B::BITS) / B::BITS
}

/// Given a row's index, returns a slice of all rows above that row, a reference to said row,
Expand All @@ -131,7 +131,7 @@ impl<B: BitBlock> BitMatrix<B> {
/// and a slice of all rows below.
#[inline]
pub fn split_at_mut(&mut self, row: usize) -> (BitSubMatrixMut<'_, B>, BitSubMatrixMut<'_, B>) {
let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
let (first, second) = unsafe { self.bit_vec.storage_mut().split_at_mut(row * row_size) };
(
BitSubMatrixMut::new(first, self.row_bits),
Expand Down Expand Up @@ -198,7 +198,7 @@ impl<B: BitBlock> Index<usize> for BitMatrix<B> {

#[inline]
fn index(&self, row: usize) -> &Self::Output {
let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
BitSlice::new(&self.bit_vec.storage()[row * row_size..(row + 1) * row_size])
}
}
Expand All @@ -207,7 +207,7 @@ impl<B: BitBlock> Index<usize> for BitMatrix<B> {
impl<B: BitBlock> IndexMut<usize> for BitMatrix<B> {
#[inline]
fn index_mut(&mut self, row: usize) -> &mut Self::Output {
let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
// Safety:
// This does not introduce any memory unsafety despite the `unsafe` keyword.
unsafe {
Expand All @@ -225,7 +225,7 @@ impl<B: BitBlock> Index<(usize, usize)> for BitMatrix<B> {

#[inline]
fn index(&self, (row, col): (usize, usize)) -> &bool {
let row_size_in_bits = round_up_to_next(self.row_bits, B::bits());
let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS);
if self.bit_vec.get(row * row_size_in_bits + col).unwrap() {
&TRUE
} else {
Expand Down
18 changes: 9 additions & 9 deletions matrix/src/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl<Block: BitBlock> BitSlice<Block> {
#[inline]
pub fn new(slice: &[Block]) -> &Self {
// Safety:
// This is the only way to construct a custom DST.
// This is currently the only way to construct a custom DST.
// We wish the layout of DSTs were defined.
unsafe { mem::transmute(slice) }
}
Expand All @@ -26,7 +26,7 @@ impl<Block: BitBlock> BitSlice<Block> {
#[inline]
pub fn new_mut(slice: &mut [Block]) -> &mut Self {
// Safety:
// This is the only way to construct a custom DST.
// This is currently the only way to construct a custom DST.
// We wish the layout of DSTs were defined.
unsafe { mem::transmute(slice) }
}
Expand All @@ -50,21 +50,21 @@ impl<Block: BitBlock> BitSlice<Block> {
/// Returns `true` if a bit is enabled in the bit vector slice, or `false` otherwise.
#[inline]
pub fn get(&self, bit: usize) -> bool {
let (block, i) = div_rem(bit, Block::bits());
let (block, i) = div_rem(bit, Block::BITS);
match self.slice.get(block) {
None => false,
Some(&b) => (b & (Block::one() << i)) != Block::zero(),
Some(&b) => (b & (Block::ONE << i)) != Block::ZERO,
}
}

/// Returns a small integer-sized slice of the bit vector slice.
#[inline]
pub fn small_slice_aligned(&self, bit: usize, len: u8) -> Block {
let (block, i) = div_rem(bit, Block::bits());
let (block, i) = div_rem(bit, Block::BITS);
match self.slice.get(block) {
None => Block::zero(),
None => Block::ZERO,
Some(&b) => {
let len_mask = (Block::one() << len as usize) - Block::one();
let len_mask = (Block::ONE << len as usize) - Block::ONE;
(b >> i) & len_mask
}
}
Expand All @@ -78,11 +78,11 @@ impl<Block: BitBlock> ops::Index<usize> for BitSlice<Block> {

#[inline]
fn index(&self, bit: usize) -> &bool {
let (block, i) = div_rem(bit, Block::bits());
let (block, i) = div_rem(bit, Block::BITS);
match self.slice.get(block) {
None => &FALSE,
Some(&b) => {
if (b & (Block::one() << i)) != Block::zero() {
if (b & (Block::ONE << i)) != Block::ZERO {
&TRUE
} else {
&FALSE
Expand Down
29 changes: 13 additions & 16 deletions matrix/src/submatrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ impl<'a, B: BitBlock> BitSubMatrix<'a, B> {
#[inline]
pub unsafe fn from_raw_parts(ptr: *const B, rows: usize, row_bits: usize) -> Self {
BitSubMatrix {
slice: slice::from_raw_parts(
ptr,
round_up_to_next(row_bits, B::bits()) / B::bits() * rows,
),
slice: slice::from_raw_parts(ptr, round_up_to_next(row_bits, B::BITS) / B::BITS * rows),
row_bits,
}
}
Expand All @@ -53,12 +50,12 @@ impl<'a, B: BitBlock> BitSubMatrix<'a, B> {
// We wish the layout of DSTs were defined.
unsafe { mem::transmute(arg) }
}
let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits();
let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS;
self.slice.chunks(row_size).map(f::<B>)
}

fn row_size(&self) -> usize {
round_up_to_next(self.row_bits, B::bits()) / B::bits()
round_up_to_next(self.row_bits, B::BITS) / B::BITS
}
}

Expand All @@ -78,7 +75,7 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> {
BitSubMatrixMut {
slice: slice::from_raw_parts_mut(
ptr,
round_up_to_next(row_bits, B::bits()) / B::bits() * rows,
round_up_to_next(row_bits, B::BITS) / B::BITS * rows,
),
row_bits,
}
Expand All @@ -103,9 +100,9 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> {
/// Panics if `(row, col)` is out of bounds.
#[inline]
pub fn set(&mut self, row: usize, col: usize, enabled: bool) {
let row_size_in_bits = round_up_to_next(self.row_bits, B::bits());
let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS);
let bit = row * row_size_in_bits + col;
let (block, i) = div_rem(bit, B::bits());
let (block, i) = div_rem(bit, B::BITS);
assert!(
block < self.slice.len() && col < self.row_bits,
"invalid index given to `BitSubMatrixMut::set`"
Expand All @@ -115,9 +112,9 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> {
// We check for `block` being within bounds in the assert above.
let elt = self.slice.get_unchecked_mut(block);
if enabled {
*elt |= B::one() << i;
*elt |= B::ONE << i;
} else {
*elt = *elt & !(B::one() << i);
*elt = *elt & !(B::ONE << i);
}
}
}
Expand All @@ -129,17 +126,17 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> {
/// Unsafe if `(row, col)` is out of bounds.
#[inline]
pub unsafe fn set_unchecked(&mut self, row: usize, col: usize, enabled: bool) {
let row_size_in_bits = round_up_to_next(self.row_bits, B::bits());
let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS);
let bit = row * row_size_in_bits + col;
let (block, i) = div_rem(bit, B::bits());
let (block, i) = div_rem(bit, B::BITS);
unsafe {
// Safety:
// Unsafe if `(row, col)` is out of bounds.
let elt = self.slice.get_unchecked_mut(block);
if enabled {
*elt |= B::one() << i;
*elt |= B::ONE << i;
} else {
*elt = *elt & !(B::one() << i);
*elt = *elt & !(B::ONE << i);
}
}
}
Expand Down Expand Up @@ -242,7 +239,7 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> {
}

fn row_size(&self) -> usize {
round_up_to_next(self.row_bits, B::bits()) / B::bits()
round_up_to_next(self.row_bits, B::BITS) / B::BITS
}
}

Expand Down
2 changes: 1 addition & 1 deletion set/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ readme = "README.md"
edition = "2021"

[dependencies]
borsh = { version = "1.7.0", default-features = false, features = ["derive"], optional = true }
borsh = { version = "1.8.0", default-features = false, features = ["derive"], optional = true }
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true }
miniserde = { version = "0.1", optional = true }

Expand Down
21 changes: 9 additions & 12 deletions set/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ where
T: Iterator<Item = B>,
{
fn from_blocks(mut blocks: T) -> Self {
let h = blocks.next().unwrap_or(B::zero());
let h = blocks.next().unwrap_or(B::ZERO);
BlockIter {
tail: blocks,
head: h,
Expand Down Expand Up @@ -212,21 +212,18 @@ where
type Item = usize;

fn next(&mut self) -> Option<Self::Item> {
while self.head == B::zero() {
match self.tail.next() {
Some(w) => self.head = w,
None => return None,
}
self.head_offset += B::bits();
while self.head == B::ZERO {
self.head = self.tail.next()?;
self.head_offset += B::BITS;
}

// from the current block, isolate the
// LSB and subtract 1, producing k:
// a block with a number of set bits
// equal to the index of the LSB
let k = (self.head & (!self.head + B::one())) - B::one();
let k = (self.head & (!self.head + B::ONE)) - B::ONE;
// update block, removing the LSB
self.head = self.head & (self.head - B::one());
self.head = self.head & (self.head - B::ONE);
// return offset + (index of LSB)
Some(self.head_offset + B::count_ones(k))
}
Expand All @@ -238,7 +235,7 @@ where
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self.tail.size_hint() {
(_, Some(h)) => (0, Some((1 + h) * B::bits())),
(_, Some(h)) => (0, Some((1 + h) * B::BITS)),
_ => (0, None),
}
}
Expand All @@ -250,8 +247,8 @@ impl<B: BitBlock> Iterator for TwoBitPositions<'_, B> {
fn next(&mut self) -> Option<Self::Item> {
match (self.set.next(), self.other.next()) {
(Some(a), Some(b)) => Some((self.merge)(a, b)),
(Some(a), None) => Some((self.merge)(a, B::zero())),
(None, Some(b)) => Some((self.merge)(B::zero(), b)),
(Some(a), None) => Some((self.merge)(a, B::ZERO)),
(None, Some(b)) => Some((self.merge)(B::ZERO, b)),
_ => None,
}
}
Expand Down
Loading