Implement shrink_to
method on collections
This commit is contained in:
parent
f5631d9ac7
commit
04f6692aaf
13 changed files with 237 additions and 2 deletions
|
@ -509,6 +509,31 @@ impl<T: Ord> BinaryHeap<T> {
|
||||||
self.data.shrink_to_fit();
|
self.data.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Discards capacity with a lower bound.
|
||||||
|
///
|
||||||
|
/// The capacity will remain at least as large as both the length
|
||||||
|
/// and the supplied value.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// use std::collections::BinaryHeap;
|
||||||
|
/// let mut heap: BinaryHeap<i32> = BinaryHeap::with_capacity(100);
|
||||||
|
///
|
||||||
|
/// assert!(heap.capacity() >= 100);
|
||||||
|
/// heap.shrink_to(10);
|
||||||
|
/// assert!(heap.capacity() >= 10);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.data.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
/// Removes the greatest item from the binary heap and returns it, or `None` if it
|
/// Removes the greatest item from the binary heap and returns it, or `None` if it
|
||||||
/// is empty.
|
/// is empty.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1015,6 +1015,34 @@ impl String {
|
||||||
self.vec.shrink_to_fit()
|
self.vec.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of this `String` with a lower bound.
|
||||||
|
///
|
||||||
|
/// The capacity will remain at least as large as both the length
|
||||||
|
/// and the supplied value.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// let mut s = String::from("foo");
|
||||||
|
///
|
||||||
|
/// s.reserve(100);
|
||||||
|
/// assert!(s.capacity() >= 100);
|
||||||
|
///
|
||||||
|
/// s.shrink_to(10);
|
||||||
|
/// assert!(s.capacity() >= 10);
|
||||||
|
/// s.shrink_to(0);
|
||||||
|
/// assert!(s.capacity() >= 3);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.vec.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
/// Appends the given [`char`] to the end of this `String`.
|
/// Appends the given [`char`] to the end of this `String`.
|
||||||
///
|
///
|
||||||
/// [`char`]: ../../std/primitive.char.html
|
/// [`char`]: ../../std/primitive.char.html
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
use core::cmp::Ordering;
|
use core::cmp::{self, Ordering};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::hash::{self, Hash};
|
use core::hash::{self, Hash};
|
||||||
use core::intrinsics::{arith_offset, assume};
|
use core::intrinsics::{arith_offset, assume};
|
||||||
|
@ -586,6 +586,31 @@ impl<T> Vec<T> {
|
||||||
self.buf.shrink_to_fit(self.len);
|
self.buf.shrink_to_fit(self.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of the vector with a lower bound.
|
||||||
|
///
|
||||||
|
/// The capacity will remain at least as large as both the length
|
||||||
|
/// and the supplied value.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// let mut vec = Vec::with_capacity(10);
|
||||||
|
/// vec.extend([1, 2, 3].iter().cloned());
|
||||||
|
/// assert_eq!(vec.capacity(), 10);
|
||||||
|
/// vec.shrink_to(4);
|
||||||
|
/// assert!(vec.capacity() >= 4);
|
||||||
|
/// vec.shrink_to(0);
|
||||||
|
/// assert!(vec.capacity() >= 3);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts the vector into [`Box<[T]>`][owned slice].
|
/// Converts the vector into [`Box<[T]>`][owned slice].
|
||||||
///
|
///
|
||||||
/// Note that this will drop any excess capacity.
|
/// Note that this will drop any excess capacity.
|
||||||
|
|
|
@ -676,9 +676,42 @@ impl<T> VecDeque<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "deque_extras_15", since = "1.5.0")]
|
#[stable(feature = "deque_extras_15", since = "1.5.0")]
|
||||||
pub fn shrink_to_fit(&mut self) {
|
pub fn shrink_to_fit(&mut self) {
|
||||||
|
self.shrink_to(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of the `VecDeque` with a lower bound.
|
||||||
|
///
|
||||||
|
/// The capacity will remain at least as large as both the length
|
||||||
|
/// and the supplied value.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// use std::collections::VecDeque;
|
||||||
|
///
|
||||||
|
/// let mut buf = VecDeque::with_capacity(15);
|
||||||
|
/// buf.extend(0..4);
|
||||||
|
/// assert_eq!(buf.capacity(), 15);
|
||||||
|
/// buf.shrink_to(6);
|
||||||
|
/// assert!(buf.capacity() >= 6);
|
||||||
|
/// buf.shrink_to(0);
|
||||||
|
/// assert!(buf.capacity() >= 4);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
|
||||||
|
|
||||||
// +1 since the ringbuffer always leaves one space empty
|
// +1 since the ringbuffer always leaves one space empty
|
||||||
// len + 1 can't overflow for an existing, well-formed ringbuffer.
|
// len + 1 can't overflow for an existing, well-formed ringbuffer.
|
||||||
let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
|
let target_cap = cmp::max(
|
||||||
|
cmp::max(min_capacity, self.len()) + 1,
|
||||||
|
MINIMUM_CAPACITY + 1
|
||||||
|
).next_power_of_two();
|
||||||
|
|
||||||
if target_cap < self.cap() {
|
if target_cap < self.cap() {
|
||||||
// There are three cases of interest:
|
// There are three cases of interest:
|
||||||
// All elements are out of desired bounds
|
// All elements are out of desired bounds
|
||||||
|
|
|
@ -910,6 +910,46 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of the map with a lower limit. It will drop
|
||||||
|
/// down no lower than the supplied limit while maintaining the internal rules
|
||||||
|
/// and possibly leaving some space in accordance with the resize policy.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
|
||||||
|
/// map.insert(1, 2);
|
||||||
|
/// map.insert(3, 4);
|
||||||
|
/// assert!(map.capacity() >= 100);
|
||||||
|
/// map.shrink_to(10);
|
||||||
|
/// assert!(map.capacity() >= 10);
|
||||||
|
/// map.shrink_to(0);
|
||||||
|
/// assert!(map.capacity() >= 2);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
|
||||||
|
|
||||||
|
let new_raw_cap = self.resize_policy.raw_capacity(max(self.len(), min_capacity));
|
||||||
|
if self.raw_capacity() != new_raw_cap {
|
||||||
|
let old_table = replace(&mut self.table, RawTable::new(new_raw_cap));
|
||||||
|
let old_size = old_table.size();
|
||||||
|
|
||||||
|
// Shrink the table. Naive algorithm for resizing:
|
||||||
|
for (h, k, v) in old_table.into_iter() {
|
||||||
|
self.insert_hashed_nocheck(h, k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(self.table.size(), old_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Insert a pre-hashed key-value pair, without first checking
|
/// Insert a pre-hashed key-value pair, without first checking
|
||||||
/// that there's enough room in the buckets. Returns a reference to the
|
/// that there's enough room in the buckets. Returns a reference to the
|
||||||
/// newly insert value.
|
/// newly insert value.
|
||||||
|
|
|
@ -292,6 +292,34 @@ impl<T, S> HashSet<T, S>
|
||||||
self.map.shrink_to_fit()
|
self.map.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of the set with a lower limit. It will drop
|
||||||
|
/// down no lower than the supplied limit while maintaining the internal rules
|
||||||
|
/// and possibly leaving some space in accordance with the resize policy.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// use std::collections::HashSet;
|
||||||
|
///
|
||||||
|
/// let mut set = HashSet::with_capacity(100);
|
||||||
|
/// set.insert(1);
|
||||||
|
/// set.insert(2);
|
||||||
|
/// assert!(set.capacity() >= 100);
|
||||||
|
/// set.shrink_to(10);
|
||||||
|
/// assert!(set.capacity() >= 10);
|
||||||
|
/// set.shrink_to(0);
|
||||||
|
/// assert!(set.capacity() >= 2);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.map.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator visiting all elements in arbitrary order.
|
/// An iterator visiting all elements in arbitrary order.
|
||||||
/// The iterator element type is `&'a T`.
|
/// The iterator element type is `&'a T`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -295,6 +295,36 @@ impl OsString {
|
||||||
self.inner.shrink_to_fit()
|
self.inner.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shrinks the capacity of the `OsString` with a lower bound.
|
||||||
|
///
|
||||||
|
/// The capacity will remain at least as large as both the length
|
||||||
|
/// and the supplied value.
|
||||||
|
///
|
||||||
|
/// Panics if the current capacity is smaller than the supplied
|
||||||
|
/// minimum capacity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(shrink_to)]
|
||||||
|
/// use std::ffi::OsString;
|
||||||
|
///
|
||||||
|
/// let mut s = OsString::from("foo");
|
||||||
|
///
|
||||||
|
/// s.reserve(100);
|
||||||
|
/// assert!(s.capacity() >= 100);
|
||||||
|
///
|
||||||
|
/// s.shrink_to(10);
|
||||||
|
/// assert!(s.capacity() >= 10);
|
||||||
|
/// s.shrink_to(0);
|
||||||
|
/// assert!(s.capacity() >= 3);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.inner.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts this `OsString` into a boxed [`OsStr`].
|
/// Converts this `OsString` into a boxed [`OsStr`].
|
||||||
///
|
///
|
||||||
/// [`OsStr`]: struct.OsStr.html
|
/// [`OsStr`]: struct.OsStr.html
|
||||||
|
|
|
@ -299,6 +299,7 @@
|
||||||
#![feature(raw)]
|
#![feature(raw)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(stdsimd)]
|
#![feature(stdsimd)]
|
||||||
|
#![feature(shrink_to)]
|
||||||
#![feature(slice_bytes)]
|
#![feature(slice_bytes)]
|
||||||
#![feature(slice_concat_ext)]
|
#![feature(slice_concat_ext)]
|
||||||
#![feature(slice_internals)]
|
#![feature(slice_internals)]
|
||||||
|
|
|
@ -104,6 +104,11 @@ impl Buf {
|
||||||
self.inner.shrink_to_fit()
|
self.inner.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.inner.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &Slice {
|
pub fn as_slice(&self) -> &Slice {
|
||||||
unsafe { mem::transmute(&*self.inner) }
|
unsafe { mem::transmute(&*self.inner) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,11 @@ impl Buf {
|
||||||
self.inner.shrink_to_fit()
|
self.inner.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.inner.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &Slice {
|
pub fn as_slice(&self) -> &Slice {
|
||||||
unsafe { mem::transmute(&*self.inner) }
|
unsafe { mem::transmute(&*self.inner) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,11 @@ impl Buf {
|
||||||
self.inner.shrink_to_fit()
|
self.inner.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.inner.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &Slice {
|
pub fn as_slice(&self) -> &Slice {
|
||||||
unsafe { mem::transmute(&*self.inner) }
|
unsafe { mem::transmute(&*self.inner) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,11 @@ impl Buf {
|
||||||
self.inner.shrink_to_fit()
|
self.inner.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.inner.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_box(self) -> Box<Slice> {
|
pub fn into_box(self) -> Box<Slice> {
|
||||||
unsafe { mem::transmute(self.inner.into_box()) }
|
unsafe { mem::transmute(self.inner.into_box()) }
|
||||||
|
|
|
@ -253,6 +253,11 @@ impl Wtf8Buf {
|
||||||
self.bytes.shrink_to_fit()
|
self.bytes.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
|
self.bytes.shrink_to(min_capacity)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue