Skip to content

Commit

Permalink
Optimized Clone::clone_from implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
james7132 committed Apr 14, 2024
1 parent ca4dd26 commit 27d64f6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ impl Hash for FixedBitSet {

impl PartialEq for FixedBitSet {
fn eq(&self, other: &Self) -> bool {
self.as_simd_slice().eq(other.as_simd_slice()) && self.length == other.length
self.length == other.length && self.as_simd_slice().eq(other.as_simd_slice())
}
}

Expand Down Expand Up @@ -1406,6 +1406,31 @@ impl Clone for FixedBitSet {
fn clone(&self) -> Self {
Self::from_blocks_and_len(Vec::from(self.as_simd_slice()), self.length)
}

#[inline]
fn clone_from(&mut self, source: &Self) {
{
let me = self.as_mut_simd_slice();
let them = source.as_simd_slice();
match me.len().cmp(&them.len()) {
Ordering::Greater => {
let (head, tail) = me.split_at_mut(them.len());
head.copy_from_slice(them);
tail.fill(SimdBlock::NONE);
self.length = source.length;
return;
}
Ordering::Equal => {
me.copy_from_slice(them);
self.length = source.length;
return;
}
// Self is smaller than the source, this requires allocation.
Ordering::Less => {}
}
}
*self = source.clone();
}
}

/// Return **true** if the bit is enabled in the bitset,
Expand Down
27 changes: 27 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1284,3 +1284,30 @@ fn test_is_full() {
fb.insert_range(..);
assert!(fb.is_full());
}

#[test]
fn clone() {
let mut fb = FixedBitSet::with_capacity(10000);
fb.set(11, true);
fb.set(12, true);
fb.set(7, true);
fb.set(35, true);
fb.set(40, true);
fb.set(77, true);
fb.set(95, true);
fb.set(50, true);
fb.set(99, true);

let fb_clone = fb.clone();
let mut fb_clone_from_smaller = FixedBitSet::with_capacity(1000000);
let mut fb_clone_from_same = FixedBitSet::with_capacity(10000);
let mut fb_clone_from_bigger = FixedBitSet::with_capacity(100);
fb_clone_from_smaller.clone_from(&fb);
fb_clone_from_same.clone_from(&fb);
fb_clone_from_bigger.clone_from(&fb);

assert_eq!(&fb, &fb_clone);
assert_eq!(&fb, &fb_clone_from_smaller);
assert_eq!(&fb, &fb_clone_from_same);
assert_eq!(&fb, &fb_clone_from_bigger);
}

0 comments on commit 27d64f6

Please sign in to comment.