From 8718c40d6b37e2ef0de20d4b055492c29548db11 Mon Sep 17 00:00:00 2001 From: Andres Franco <86476313+and-franco@users.noreply.github.com> Date: Mon, 21 Aug 2023 13:47:23 +0200 Subject: [PATCH] Make Slab::clone_from avoid reallocation (#137) --- src/lib.rs | 17 ++++++++++++++++- tests/slab.rs | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index e23ead9..ebca7e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 { // Chunk of memory entries: Vec>, @@ -142,6 +141,22 @@ pub struct Slab { next: usize, } +impl Clone for Slab 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 Default for Slab { fn default() -> Self { Slab::new() diff --git a/tests/slab.rs b/tests/slab.rs index 900eed3..4799c1d 100644 --- a/tests/slab.rs +++ b/tests/slab.rs @@ -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); +}