Skip to content

Commit 0e18ddc

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, mostly mirroring what std::collections::HashMap offers except returning a standard Vec instead of a Drain. 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 0e18ddc

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
Cargo.lock

src/lib.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,14 @@ 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 `Vec`.
405+
/// Keeps the allocated memory for reuse.
406+
pub fn drain(&mut self) -> Vec<(K, V)> {
407+
let cap = self.indices.capacity();
408+
replace(&mut self.indices, vec![Pos::none(); cap]);
409+
self.entries.drain(..).map(|bucket| (bucket.key, bucket.value)).collect()
410+
}
403411
}
404412

405413
/// Trait for the "size class". Either u32 or u64 depending on the index
@@ -1690,4 +1698,39 @@ mod tests {
16901698
assert_ne!(map_a, map_c);
16911699
assert_ne!(map_c, map_a);
16921700
}
1701+
1702+
1703+
#[test]
1704+
fn drain_basic() {
1705+
let mut map_a = OrderMap::new();
1706+
map_a.insert(1, "1");
1707+
map_a.insert(2, "2");
1708+
let entries = map_a.drain();
1709+
assert!(map_a.is_empty());
1710+
assert_eq!(entries.len(), 2);
1711+
assert!(map_a.is_empty());
1712+
1713+
map_a.insert(3, "3");
1714+
assert!(!map_a.is_empty());
1715+
assert_eq!(map_a.len(), 1);
1716+
assert!(map_a.get(&3).is_some());
1717+
assert!(map_a.get(&1).is_none());
1718+
}
1719+
1720+
#[test]
1721+
fn drain_after_resize() {
1722+
let mut map_a = OrderMap::with_capacity(2);
1723+
map_a.insert(1, "1");
1724+
map_a.insert(2, "2");
1725+
map_a.insert(3, "3");
1726+
let entries = map_a.drain();
1727+
assert!(map_a.is_empty());
1728+
assert_eq!(entries.len(), 3);
1729+
1730+
map_a.insert(4, "4");
1731+
assert!(!map_a.is_empty());
1732+
assert_eq!(map_a.len(), 1);
1733+
assert!(map_a.get(&4).is_some());
1734+
assert!(map_a.get(&1).is_none());
1735+
}
16931736
}

0 commit comments

Comments
 (0)