Skip to content

Commit

Permalink
Add ensure_capacity and rename min to len
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Apr 1, 2019
1 parent e8b3aea commit 59ff059
Showing 1 changed file with 26 additions and 15 deletions.
41 changes: 26 additions & 15 deletions src/libarena/lib.rs
Expand Up @@ -161,14 +161,21 @@ impl<T> TypedArena<T> {
available_capacity_bytes >= at_least_bytes available_capacity_bytes >= at_least_bytes
} }


/// Ensures there's enough space in the current chunk to fit `len` objects.
#[inline]
fn ensure_capacity(&self, len: usize) {
if !self.can_allocate(len) {
self.grow(len);
debug_assert!(self.can_allocate(len));
}
}

#[inline] #[inline]
unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T { unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T {
assert!(mem::size_of::<T>() != 0); assert!(mem::size_of::<T>() != 0);
assert!(len != 0); assert!(len != 0);


if !self.can_allocate(len) { self.ensure_capacity(len);
self.grow(len);
}


let start_ptr = self.ptr.get(); let start_ptr = self.ptr.get();
self.ptr.set(start_ptr.add(len)); self.ptr.set(start_ptr.add(len));
Expand Down Expand Up @@ -203,19 +210,20 @@ impl<T> TypedArena<T> {


match size_hint { match size_hint {
(min, Some(max)) if min == max => { (min, Some(max)) if min == max => {
if min == 0 { // We know the exact number of elements the iterator will produce here
let len = min;

if len == 0 {
return &mut []; return &mut [];
} }


if !self.can_allocate(min) { self.ensure_capacity(len);
self.grow(min);
}


let slice = self.ptr.get(); let slice = self.ptr.get();


unsafe { unsafe {
let mut ptr = self.ptr.get(); let mut ptr = self.ptr.get();
for _ in 0..min { for _ in 0..len {
// Write into uninitialized memory. // Write into uninitialized memory.
ptr::write(ptr, iter.next().unwrap()); ptr::write(ptr, iter.next().unwrap());
// Advance the pointer. // Advance the pointer.
Expand All @@ -224,7 +232,7 @@ impl<T> TypedArena<T> {
// we destroy the correct amount // we destroy the correct amount
self.ptr.set(ptr); self.ptr.set(ptr);
} }
slice::from_raw_parts_mut(slice, min) slice::from_raw_parts_mut(slice, len)
} }
} }
_ => { _ => {
Expand All @@ -239,7 +247,7 @@ impl<T> TypedArena<T> {
let len = vec.len(); let len = vec.len();
let start_ptr = self.alloc_raw_slice(len); let start_ptr = self.alloc_raw_slice(len);
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
vev.set_len(0); vec.set_len(0);
slice::from_raw_parts_mut(start_ptr, len) slice::from_raw_parts_mut(start_ptr, len)
} }
}) })
Expand Down Expand Up @@ -488,16 +496,19 @@ impl DroplessArena {


match size_hint { match size_hint {
(min, Some(max)) if min == max => { (min, Some(max)) if min == max => {
if min == 0 { // We know the exact number of elements the iterator will produce here
let len = min;

if len == 0 {
return &mut [] return &mut []
} }
let size = min.checked_mul(mem::size_of::<T>()).unwrap(); let size = len.checked_mul(mem::size_of::<T>()).unwrap();
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T; let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
unsafe { unsafe {
for i in 0..min { for i in 0..len {
ptr::write(mem.offset(i as isize), iter.next().unwrap()) ptr::write(mem.offset(i as isize), iter.next().unwrap())
} }
slice::from_raw_parts_mut(mem, min) slice::from_raw_parts_mut(mem, len)
} }
} }
(_, _) => { (_, _) => {
Expand All @@ -515,7 +526,7 @@ impl DroplessArena {
mem::align_of::<T>() mem::align_of::<T>()
) as *mut _ as *mut T; ) as *mut _ as *mut T;
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
vev.set_len(0); vec.set_len(0);
slice::from_raw_parts_mut(start_ptr, len) slice::from_raw_parts_mut(start_ptr, len)
} }
}) })
Expand Down

0 comments on commit 59ff059

Please sign in to comment.