Skip to content

Commit 76b3598

Browse files
author
Steve Jenson
committed
Adds a OrderMap::drain() method
Problem: Porting some code that used HashMap's drain to OrderMap revealed a small API gap. Solution: Added a drain method, mirroring std::collection::HashMap's drain method. drain() provides an efficient way to remove all values without shrinking the capacity of the original OrderMap. Validation: Added unit tests and ported an existing HashMap::drain() user to OrderMap::drain
1 parent dc0be46 commit 76b3598

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
Cargo.lock

src/lib.rs

+58
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,18 @@ impl<K, V, S> OrderMap<K, V, S>
400400
pub fn capacity(&self) -> usize {
401401
usable_capacity(self.raw_capacity())
402402
}
403+
404+
/// Clears the `OrderMap`, returning all key-value pairs as a `Drain`.
405+
/// Keeps the allocated memory for reuse.
406+
pub fn drain(&mut self) -> Drain<K, V> {
407+
for i in &mut self.indices {
408+
*i = Pos::none();
409+
}
410+
411+
Drain {
412+
inner: self.entries.drain(..),
413+
}
414+
}
403415
}
404416

405417
/// Trait for the "size class". Either u32 or u64 depending on the index
@@ -1496,6 +1508,17 @@ impl<K, V, S> Eq for OrderMap<K, V, S>
14961508
{
14971509
}
14981510

1511+
pub struct Drain<'a, K, V> where K: 'a, V: 'a {
1512+
inner: ::std::vec::Drain<'a, Bucket<K, V>>
1513+
}
1514+
1515+
impl<'a, K, V> Iterator for Drain<'a, K, V> {
1516+
type Item = (K, V);
1517+
fn next(&mut self) -> Option<Self::Item> {
1518+
self.inner.next().map(|bucket| (bucket.key, bucket.value))
1519+
}
1520+
}
1521+
14991522
#[cfg(test)]
15001523
mod tests {
15011524
use super::*;
@@ -1690,4 +1713,39 @@ mod tests {
16901713
assert_ne!(map_a, map_c);
16911714
assert_ne!(map_c, map_a);
16921715
}
1716+
1717+
1718+
#[test]
1719+
fn drain_basic() {
1720+
let mut map_a = OrderMap::new();
1721+
map_a.insert(1, "1");
1722+
map_a.insert(2, "2");
1723+
let entries: Vec<(u32, &str)> = map_a.drain().collect();
1724+
assert!(map_a.is_empty());
1725+
assert_eq!(entries.len(), 2);
1726+
assert!(map_a.is_empty());
1727+
1728+
map_a.insert(3, "3");
1729+
assert!(!map_a.is_empty());
1730+
assert_eq!(map_a.len(), 1);
1731+
assert!(map_a.get(&3).is_some());
1732+
assert!(map_a.get(&1).is_none());
1733+
}
1734+
1735+
#[test]
1736+
fn drain_after_resize() {
1737+
let mut map_a = OrderMap::with_capacity(2);
1738+
map_a.insert(1, "1");
1739+
map_a.insert(2, "2");
1740+
map_a.insert(3, "3");
1741+
let entries: Vec<(u32, &str)> = map_a.drain().collect();
1742+
assert!(map_a.is_empty());
1743+
assert_eq!(entries.len(), 3);
1744+
1745+
map_a.insert(4, "4");
1746+
assert!(!map_a.is_empty());
1747+
assert_eq!(map_a.len(), 1);
1748+
assert!(map_a.get(&4).is_some());
1749+
assert!(map_a.get(&1).is_none());
1750+
}
16931751
}

0 commit comments

Comments
 (0)