From 1827213d02ed709e328303e79d49cad8e0ad3385 Mon Sep 17 00:00:00 2001 From: Aaron Liblong Date: Wed, 3 Dec 2014 04:00:42 -0500 Subject: [PATCH 1/4] Add reserve* functions to Vec and VecMap --- src/libcollections/vec.rs | 122 +++++++++++++++++++++++- src/libcollections/vec_map.rs | 168 ++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+), 4 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 5edd3d0b780be..fc12a3462d995 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -619,9 +619,9 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec: Vec = vec![1]; + /// let mut vec = Vec::new(); /// vec.reserve(10); - /// assert!(vec.capacity() >= 11); + /// assert!(vec.capacity() >= 9); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { @@ -656,9 +656,9 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec: Vec = vec![1]; + /// let mut vec = Vec::new(); /// vec.reserve_exact(10); - /// assert!(vec.capacity() >= 11); + /// assert!(vec.capacity() >= 9); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { @@ -670,6 +670,54 @@ impl Vec { } } + /// Reserves the minimum capacity for an element to be inserted at `index` in the given + /// `Vec`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut vec = Vec::new(); + /// vec.reserve_index(10); + /// assert!(vec.capacity() >= 11); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_index(&mut self, index: uint) { + let len = self.len(); + if index >= len { + self.reserve(index - len + 1); + } + } + + /// Reserves the minimum capacity for an element to be inserted at `index` in the + /// given `Vec`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve_index` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut vec = Vec::new(); + /// vec.reserve_index_exact(10); + /// assert!(vec.capacity() >= 11); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_index_exact(&mut self, index: uint) { + let len = self.len(); + if index >= len { + self.reserve_exact(index - len + 1); + } + } + /// Shrinks the capacity of the vector as much as possible. It will drop /// down as close as possible to the length but the allocator may still /// inform the vector that there is space for a few more elements. @@ -1792,6 +1840,72 @@ mod tests { assert!(v.capacity() >= 33) } + #[test] + fn test_reserve_exact() { + let mut v = Vec::new(); + assert_eq!(v.capacity(), 0); + + v.reserve_exact(2); + assert!(v.capacity() >= 2); + + for i in range(0i, 16) { + v.push(i); + } + + assert!(v.capacity() >= 16); + v.reserve_exact(16); + assert!(v.capacity() >= 32); + + v.push(16); + + v.reserve_exact(16); + assert!(v.capacity() >= 33) + } + + #[test] + fn test_reserve_index() { + let mut v = Vec::new(); + assert_eq!(v.capacity(), 0); + + v.reserve_index(2); + assert!(v.capacity() >= 3); + + for i in range(0i, 16) { + v.push(i); + } + + assert!(v.capacity() >= 16); + v.reserve_index(16); + assert!(v.capacity() >= 17); + + v.push(16); + + v.reserve_index(32); + assert!(v.capacity() >= 33) + } + + #[test] + fn test_reserve_index_exact() { + let mut v = Vec::new(); + assert_eq!(v.capacity(), 0); + + v.reserve_index_exact(2); + assert!(v.capacity() >= 3); + + for i in range(0i, 16) { + v.push(i); + } + + assert!(v.capacity() >= 16); + v.reserve_index_exact(16); + assert!(v.capacity() >= 17); + + v.push(16); + + v.reserve_index_exact(32); + assert!(v.capacity() >= 33) + } + #[test] fn test_extend() { let mut v = Vec::new(); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 36e66ed27f3c9..2b9ed80bfeae9 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -115,6 +115,85 @@ impl VecMap { VecMap { v: Vec::with_capacity(capacity) } } + /// Reserves capacity for at least `additional` more elements to be inserted in the given + /// `VecMap`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut map = VecMap::new(); + /// map.reserve(10); + /// assert!(map.v.capacity() >= 9); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve(&mut self, additional: uint) { + self.v.reserve(additional); + } + + /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// `VecMap`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut map = VecMap::new(); + /// map.reserve_exact(10); + /// assert!(map.v.capacity() >= 9); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_exact(&mut self, additional: uint) { + self.v.reserve_exact(additional); + } + + /// Reserves the minimum capacity for an element to be inserted at `index` in the given + /// `VecMap`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut map = VecMap::new(); + /// map.reserve_index(10); + /// assert!(map.v.capacity() >= 11); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_index(&mut self, index: uint) { + self.v.reserve_index(index); + } + + /// Reserves the minimum capacity for an element to be inserted at `index` in the + /// given `VecMap`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve_index` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// let mut map = VecMap::new(); + /// map.reserve_index_exact(10); + /// assert!(map.v.capacity() >= 11); + /// ``` + pub fn reserve_index_exact(&mut self, index: uint) { + self.v.reserve_index_exact(index); + } + /// Returns an iterator visiting all keys in ascending order by the keys. /// The iterator's element type is `uint`. #[unstable = "matches collection reform specification, waiting for dust to settle"] @@ -698,6 +777,94 @@ mod test_map { assert_eq!(m.remove(&1), None); } + #[test] + fn test_reserve() { + let mut map = VecMap::new(); + assert_eq!(map.v.capacity(), 0); + + map.reserve(2); + assert!(map.v.capacity() >= 2); + + for i in range(0u, 16) { + map.insert(i, "a"); + } + + assert!(map.v.capacity() >= 16); + map.reserve(16); + assert!(map.v.capacity() >= 32); + + map.insert(16,"b"); + + map.reserve(16); + assert!(map.v.capacity() >= 33) + } + + #[test] + fn test_reserve_exact() { + let mut map = VecMap::new(); + assert_eq!(map.v.capacity(), 0); + + map.reserve_exact(2); + assert!(map.v.capacity() >= 2); + + for i in range(0u, 16) { + map.insert(i, "a"); + } + + assert!(map.v.capacity() >= 16); + map.reserve_exact(16); + assert!(map.v.capacity() >= 32); + + map.insert(16,"b"); + + map.reserve_exact(16); + assert!(map.v.capacity() >= 33) + } + + #[test] + fn test_reserve_index() { + let mut map = VecMap::new(); + assert_eq!(map.v.capacity(), 0); + + map.reserve_index(2); + assert!(map.v.capacity() >= 3); + + for i in range(0u, 16) { + map.insert(i, "a"); + } + + assert!(map.v.capacity() >= 16); + map.reserve_index(16); + assert!(map.v.capacity() >= 17); + + map.insert(16,"b"); + + map.reserve_index(32); + assert!(map.v.capacity() >= 33) + } + + #[test] + fn test_reserve_index_exact() { + let mut map = VecMap::new(); + assert_eq!(map.v.capacity(), 0); + + map.reserve_index_exact(2); + assert!(map.v.capacity() >= 3); + + for i in range(0u, 16) { + map.insert(i, "a"); + } + + assert!(map.v.capacity() >= 16); + map.reserve_index_exact(16); + assert!(map.v.capacity() >= 17); + + map.insert(16,"b"); + + map.reserve_index_exact(32); + assert!(map.v.capacity() >= 33) + } + #[test] fn test_keys() { let mut map = VecMap::new(); @@ -1046,3 +1213,4 @@ mod bench { |m, i| { m.get(&i); }); } } + From 5e1cd4f1af109af106a0853896a6b00293f71101 Mon Sep 17 00:00:00 2001 From: Aaron Liblong Date: Wed, 3 Dec 2014 04:17:16 -0500 Subject: [PATCH 2/4] Updated the doc examples with an explicit type annotation so they actually work --- src/libcollections/vec.rs | 8 ++++---- src/libcollections/vec_map.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index fc12a3462d995..60aca161f2b4a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -619,7 +619,7 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec = Vec::new(); + /// let mut vec: Vec = Vec::new(); /// vec.reserve(10); /// assert!(vec.capacity() >= 9); /// ``` @@ -656,7 +656,7 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec = Vec::new(); + /// let mut vec: Vec = Vec::new(); /// vec.reserve_exact(10); /// assert!(vec.capacity() >= 9); /// ``` @@ -680,7 +680,7 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec = Vec::new(); + /// let mut vec: Vec = Vec::new(); /// vec.reserve_index(10); /// assert!(vec.capacity() >= 11); /// ``` @@ -706,7 +706,7 @@ impl Vec { /// # Example /// /// ``` - /// let mut vec = Vec::new(); + /// let mut vec: Vec = Vec::new(); /// vec.reserve_index_exact(10); /// assert!(vec.capacity() >= 11); /// ``` diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 2b9ed80bfeae9..5f3fecd0184b0 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -125,7 +125,7 @@ impl VecMap { /// # Example /// /// ``` - /// let mut map = VecMap::new(); + /// let mut map: VecMap = VecMap::new(); /// map.reserve(10); /// assert!(map.v.capacity() >= 9); /// ``` @@ -144,7 +144,7 @@ impl VecMap { /// # Example /// /// ``` - /// let mut map = VecMap::new(); + /// let mut map: VecMap = VecMap::new(); /// map.reserve_exact(10); /// assert!(map.v.capacity() >= 9); /// ``` @@ -163,7 +163,7 @@ impl VecMap { /// # Example /// /// ``` - /// let mut map = VecMap::new(); + /// let mut map: VecMap = VecMap::new(); /// map.reserve_index(10); /// assert!(map.v.capacity() >= 11); /// ``` @@ -186,7 +186,7 @@ impl VecMap { /// # Example /// /// ``` - /// let mut map = VecMap::new(); + /// let mut map: VecMap = VecMap::new(); /// map.reserve_index_exact(10); /// assert!(map.v.capacity() >= 11); /// ``` From aba06a80819ebacf79ff4d904b1861d4b3b4b2da Mon Sep 17 00:00:00 2001 From: Aaron Liblong Date: Wed, 3 Dec 2014 04:20:31 -0500 Subject: [PATCH 3/4] Fixed the capacity assertion for reserve & reserve_exact doc examples --- src/libcollections/vec.rs | 4 ++-- src/libcollections/vec_map.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 60aca161f2b4a..f70325995ae9d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -621,7 +621,7 @@ impl Vec { /// ``` /// let mut vec: Vec = Vec::new(); /// vec.reserve(10); - /// assert!(vec.capacity() >= 9); + /// assert!(vec.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { @@ -658,7 +658,7 @@ impl Vec { /// ``` /// let mut vec: Vec = Vec::new(); /// vec.reserve_exact(10); - /// assert!(vec.capacity() >= 9); + /// assert!(vec.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 5f3fecd0184b0..6d94a58fe4c3b 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -127,7 +127,7 @@ impl VecMap { /// ``` /// let mut map: VecMap = VecMap::new(); /// map.reserve(10); - /// assert!(map.v.capacity() >= 9); + /// assert!(map.v.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { @@ -146,7 +146,7 @@ impl VecMap { /// ``` /// let mut map: VecMap = VecMap::new(); /// map.reserve_exact(10); - /// assert!(map.v.capacity() >= 9); + /// assert!(map.v.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { From f77a09824d38b538692476f2092edf1d4b5a5a6e Mon Sep 17 00:00:00 2001 From: Aaron Liblong Date: Wed, 3 Dec 2014 14:46:06 -0500 Subject: [PATCH 4/4] Added capacity() to VecMap and changed tests accordingly --- src/libcollections/vec_map.rs | 68 ++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 6d94a58fe4c3b..d4485c06974d9 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -115,6 +115,22 @@ impl VecMap { VecMap { v: Vec::with_capacity(capacity) } } + /// Returns the number of elements the `VecMap` can hold without + /// reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::VecMap; + /// let map: VecMap = VecMap::with_capacity(10); + /// assert_eq!(map.capacity(), 10); + /// ``` + #[inline] + #[stable] + pub fn capacity(&self) -> uint { + self.v.capacity() + } + /// Reserves capacity for at least `additional` more elements to be inserted in the given /// `VecMap`. The collection may reserve more space to avoid frequent reallocations. /// @@ -125,9 +141,10 @@ impl VecMap { /// # Example /// /// ``` + /// use std::collections::VecMap; /// let mut map: VecMap = VecMap::new(); /// map.reserve(10); - /// assert!(map.v.capacity() >= 10); + /// assert!(map.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve(&mut self, additional: uint) { @@ -144,9 +161,10 @@ impl VecMap { /// # Example /// /// ``` + /// use std::collections::VecMap; /// let mut map: VecMap = VecMap::new(); /// map.reserve_exact(10); - /// assert!(map.v.capacity() >= 10); + /// assert!(map.capacity() >= 10); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_exact(&mut self, additional: uint) { @@ -163,9 +181,10 @@ impl VecMap { /// # Example /// /// ``` + /// use std::collections::VecMap; /// let mut map: VecMap = VecMap::new(); /// map.reserve_index(10); - /// assert!(map.v.capacity() >= 11); + /// assert!(map.capacity() >= 11); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn reserve_index(&mut self, index: uint) { @@ -186,9 +205,10 @@ impl VecMap { /// # Example /// /// ``` + /// use std::collections::VecMap; /// let mut map: VecMap = VecMap::new(); /// map.reserve_index_exact(10); - /// assert!(map.v.capacity() >= 11); + /// assert!(map.capacity() >= 11); /// ``` pub fn reserve_index_exact(&mut self, index: uint) { self.v.reserve_index_exact(index); @@ -780,89 +800,89 @@ mod test_map { #[test] fn test_reserve() { let mut map = VecMap::new(); - assert_eq!(map.v.capacity(), 0); + assert_eq!(map.capacity(), 0); map.reserve(2); - assert!(map.v.capacity() >= 2); + assert!(map.capacity() >= 2); for i in range(0u, 16) { map.insert(i, "a"); } - assert!(map.v.capacity() >= 16); + assert!(map.capacity() >= 16); map.reserve(16); - assert!(map.v.capacity() >= 32); + assert!(map.capacity() >= 32); map.insert(16,"b"); map.reserve(16); - assert!(map.v.capacity() >= 33) + assert!(map.capacity() >= 33) } #[test] fn test_reserve_exact() { let mut map = VecMap::new(); - assert_eq!(map.v.capacity(), 0); + assert_eq!(map.capacity(), 0); map.reserve_exact(2); - assert!(map.v.capacity() >= 2); + assert!(map.capacity() >= 2); for i in range(0u, 16) { map.insert(i, "a"); } - assert!(map.v.capacity() >= 16); + assert!(map.capacity() >= 16); map.reserve_exact(16); - assert!(map.v.capacity() >= 32); + assert!(map.capacity() >= 32); map.insert(16,"b"); map.reserve_exact(16); - assert!(map.v.capacity() >= 33) + assert!(map.capacity() >= 33) } #[test] fn test_reserve_index() { let mut map = VecMap::new(); - assert_eq!(map.v.capacity(), 0); + assert_eq!(map.capacity(), 0); map.reserve_index(2); - assert!(map.v.capacity() >= 3); + assert!(map.capacity() >= 3); for i in range(0u, 16) { map.insert(i, "a"); } - assert!(map.v.capacity() >= 16); + assert!(map.capacity() >= 16); map.reserve_index(16); - assert!(map.v.capacity() >= 17); + assert!(map.capacity() >= 17); map.insert(16,"b"); map.reserve_index(32); - assert!(map.v.capacity() >= 33) + assert!(map.capacity() >= 33) } #[test] fn test_reserve_index_exact() { let mut map = VecMap::new(); - assert_eq!(map.v.capacity(), 0); + assert_eq!(map.capacity(), 0); map.reserve_index_exact(2); - assert!(map.v.capacity() >= 3); + assert!(map.capacity() >= 3); for i in range(0u, 16) { map.insert(i, "a"); } - assert!(map.v.capacity() >= 16); + assert!(map.capacity() >= 16); map.reserve_index_exact(16); - assert!(map.v.capacity() >= 17); + assert!(map.capacity() >= 17); map.insert(16,"b"); map.reserve_index_exact(32); - assert!(map.v.capacity() >= 33) + assert!(map.capacity() >= 33) } #[test]