Skip to content

Commit

Permalink
Make Slab::clone_from avoid reallocation (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
vs-andresfranco authored Aug 21, 2023
1 parent 012088c commit 8718c40
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ use core::{fmt, mem, ops, slice};
/// See the [module documentation] for more details.
///
/// [module documentation]: index.html
#[derive(Clone)]
pub struct Slab<T> {
// Chunk of memory
entries: Vec<Entry<T>>,
Expand All @@ -142,6 +141,22 @@ pub struct Slab<T> {
next: usize,
}

impl<T> Clone for Slab<T> where T: Clone {
fn clone(&self) -> Self {
Self {
entries: self.entries.clone(),
len: self.len,
next: self.next
}
}

fn clone_from(&mut self, source: &Self) {
self.entries.clone_from(&source.entries);
self.len = source.len;
self.next = source.next;
}
}

impl<T> Default for Slab<T> {
fn default() -> Self {
Slab::new()
Expand Down
21 changes: 21 additions & 0 deletions tests/slab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,3 +710,24 @@ fn try_remove() {
fn const_new() {
static _SLAB: Slab<()> = Slab::new();
}

#[test]
fn clone_from() {
let mut slab1 = Slab::new();
let mut slab2 = Slab::new();
for i in 0..5 {
slab1.insert(i);
slab2.insert(2 * i);
slab2.insert(2 * i + 1);
}
slab1.remove(1);
slab1.remove(3);
slab2.clone_from(&slab1);

let mut iter2 = slab2.iter();
assert_eq!(iter2.next(), Some((0, &0)));
assert_eq!(iter2.next(), Some((2, &2)));
assert_eq!(iter2.next(), Some((4, &4)));
assert_eq!(iter2.next(), None);
assert!(slab2.capacity() >= 10);
}

0 comments on commit 8718c40

Please sign in to comment.