Skip to content

Commit

Permalink
refactor: don't make Mut* collections waste space when copy can't…
Browse files Browse the repository at this point in the history
… be `_nonoverlapping`
  • Loading branch information
bluurryy committed Aug 22, 2024
1 parent ed5a72d commit 9db0bab
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
20 changes: 5 additions & 15 deletions src/bump_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,8 @@ where
let dst_end = nonnull::add(start, cap);
let dst = nonnull::sub(dst_end, len);

// We only copy if we can do so nonoverlappingly.
// TODO: How about we don't? This is surprising, let's not.
// This also makes the docs wrong saying that "unused capacity does not take up space".
if dst >= end {
nonnull::copy_nonoverlapping(start, dst, len);
start = dst;
}
nonnull::copy(start, dst, len);
start = dst;
}

self.set_pos(nonnull::addr(start), T::ALIGN);
Expand All @@ -166,14 +161,9 @@ where
let dst = nonnull::sub(end, cap);
let dst_end = nonnull::add(dst, len);

// We only copy if we can do so nonoverlappingly.
// TODO: How about we don't? This is surprising, let's not.
// This also makes the docs wrong saying that "unused capacity does not take up space".
if dst_end <= start {
nonnull::copy_nonoverlapping(start, dst, len);
start = dst;
end = dst_end;
}
nonnull::copy(start, dst, len);
start = dst;
end = dst_end;
}

self.set_pos(nonnull::addr(end), T::ALIGN);
Expand Down
7 changes: 3 additions & 4 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@ mod coerce_unsized;

mod alloc_iter;
mod alloc_slice;

mod allocator_api;
mod bump_vec_doc;
mod from_std;
mod mut_bump_vec_doc;
mod vec;

mod bump_vec_doc;
mod mut_bump_vec_rev_doc;
mod mut_collections_do_not_waste_space;
mod panic_safety;
mod pool;
mod unaligned_collection;
mod vec;

mod alloc_fmt;
#[cfg(feature = "serde")]
Expand Down
41 changes: 41 additions & 0 deletions src/tests/mut_collections_do_not_waste_space.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::iter;

use crate::{Bump, MutBumpVec, MutBumpVecRev};
use allocator_api2::alloc::Global;

use super::either_way;

pub fn vec<const UP: bool>() {
let mut bump: Bump<Global, 1, UP> = Bump::with_size(512);
assert_eq!(bump.stats().size(), 512 - size_of::<[usize; 2]>());

for size in [0, 100, 200, 300, 400] {
bump.reset();

let mut vec: MutBumpVec<u8, Global, 1, UP> = MutBumpVec::new_in(&mut bump);
vec.extend(iter::repeat(0).take(size));
assert_eq!(vec.stats().allocated(), 0); // `Mut*` allocations don't bump the pointer
_ = vec.into_slice();
assert_eq!(bump.stats().allocated(), size);
}
}

pub fn vec_rev<const UP: bool>() {
let mut bump: Bump<Global, 1, UP> = Bump::with_size(512);
assert_eq!(bump.stats().size(), 512 - size_of::<[usize; 2]>());

for size in [0, 100, 200, 300, 400] {
bump.reset();

let mut vec: MutBumpVecRev<u8, Global, 1, UP> = MutBumpVecRev::new_in(&mut bump);
vec.extend(iter::repeat(0).take(size));
assert_eq!(vec.stats().allocated(), 0); // `Mut*` allocations don't bump the pointer
_ = vec.into_slice();
assert_eq!(bump.stats().allocated(), size);
}
}

either_way! {
vec
vec_rev
}

0 comments on commit 9db0bab

Please sign in to comment.