From 1ffc9cb6fbaa61e0e79811c392f34a601d8fd98b Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Thu, 22 Feb 2018 14:04:36 +0100 Subject: [PATCH 1/2] Remove trailing whitespace --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8e8bacb..6660919 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,13 +70,14 @@ impl FixedBitSet length: bits, } } + /// Create a new **FixedBitSet** with a specific number of bits, /// initialized from provided blocks. /// /// If the blocks are not the exact size needed for the capacity /// they will be padded with zeros (if shorter) or truncated to /// the capacity (if longer). - /// + /// /// For example: /// ``` /// let data = vec![4]; From 6c79c7c412aff1a42b31d541fa572bd684e852d5 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Thu, 22 Feb 2018 14:43:26 +0100 Subject: [PATCH 2/2] Implement `ones()` using `trailing_zeros()` Fixes #17. --- src/lib.rs | 55 ++++++++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6660919..26086e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -303,17 +303,15 @@ impl FixedBitSet match self.as_slice().split_first() { Some((&block, rem)) => { Ones { - current_bit_idx: 0, - current_block_idx: 0, - current_block: block, + bitset: block, + block_idx: 0, remaining_blocks: rem } } None => { Ones { - current_bit_idx: 0, - current_block_idx: 0, - current_block: 0, + bitset: 0, + block_idx: 0, remaining_blocks: &[] } } @@ -594,10 +592,9 @@ impl Iterator for Masks { /// /// This struct is created by the [`FixedBitSet::ones`] method. pub struct Ones<'a> { - current_bit_idx: usize, - current_block_idx: usize, + bitset: Block, + block_idx: usize, remaining_blocks: &'a [Block], - current_block: Block } impl<'a> Iterator for Ones<'a> { @@ -605,38 +602,18 @@ impl<'a> Iterator for Ones<'a> { #[inline] fn next(&mut self) -> Option { - let mut block = self.current_block; - let mut idx = self.current_bit_idx; - - loop { - loop { - if (block & 1) == 1 { - self.current_block = block >> 1; - self.current_bit_idx = idx + 1; - return Some(idx); - } - // reordering the two lines below makes a huge (2x) difference in performance! - block = block >> 1; - idx += 1; - if block == 0 { - break; - } - } - - // go to next block - match self.remaining_blocks.split_first() { - Some((&next_block, rest)) => { - self.remaining_blocks = rest; - self.current_block_idx += 1; - idx = self.current_block_idx * BITS; - block = next_block; - } - None => { - // last block => done - return None; - } + while self.bitset == 0 { + if self.remaining_blocks.is_empty() { + return None; } + self.bitset = self.remaining_blocks[0]; + self.remaining_blocks = &self.remaining_blocks[1..]; + self.block_idx += 1; } + let t = self.bitset & (0 as Block).wrapping_sub(self.bitset); + let r = self.bitset.trailing_zeros() as usize; + self.bitset ^= t; + Some(self.block_idx * BITS + r) } }