Skip to content

Commit e1029cf

Browse files
committed
Add CHashMap::clear() like libstd.
1 parent 4d7b3ec commit e1029cf

File tree

3 files changed

+65
-29
lines changed

3 files changed

+65
-29
lines changed

chashmap/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "chashmap"
3-
version = "1.1.0"
3+
version = "1.2.0"
44
authors = ["ticki <[email protected]>"]
55
description = "Fast, concurrent hash maps with extensive API."
66
repository = "https://github.com/ticki/tfs"

chashmap/src/lib.rs

+44-28
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,50 @@ impl<K, V> CHashMap<K, V> {
586586
pub fn new() -> CHashMap<K, V> {
587587
CHashMap::with_capacity(DEFAULT_INITIAL_CAPACITY)
588588
}
589+
590+
/// Get the number of entries in the hash table.
591+
///
592+
/// This is entirely atomic, and will not acquire any locks.
593+
pub fn len(&self) -> usize {
594+
self.len.load(ORDERING)
595+
}
596+
597+
/// Get the capacity of the hash table.
598+
///
599+
/// The capacity is equal to the number of entries the table can hold before reallocating.
600+
pub fn capacity(&self) -> usize {
601+
self.buckets() * MAX_LOAD_FACTOR_NUM / MAX_LOAD_FACTOR_DENOM
602+
}
603+
604+
/// Get the number of buckets of the hash table.
605+
///
606+
/// "Buckets" refers to the amount of potential entries in the inner table. It is different
607+
/// from capacity, in the sense that the map cannot hold this number of entries, since it needs
608+
/// to keep the load factor low.
609+
pub fn buckets(&self) -> usize {
610+
self.table.read().buckets.len()
611+
}
612+
613+
/// Is the hash table empty?
614+
pub fn is_empty(&self) -> bool {
615+
self.len() == 0
616+
}
617+
618+
/// Clear the map.
619+
///
620+
/// This clears the hash map and returns the previous version of the map.
621+
///
622+
/// It is relatively efficient, although it needs to write lock a RW lock.
623+
pub fn clear(&self) -> CHashMap<K, V> {
624+
// Acquire a writable lock.
625+
let mut lock = self.table.write();
626+
CHashMap {
627+
// Replace the old table with an empty initial table.
628+
table: RwLock::new(mem::replace(&mut *lock, Table::new(DEFAULT_INITIAL_CAPACITY))),
629+
// Replace the length with 0 and use the old length.
630+
len: AtomicUsize::new(self.len.swap(0, ORDERING)),
631+
}
632+
}
589633
}
590634

591635
impl<K: PartialEq + Hash, V> CHashMap<K, V> {
@@ -640,34 +684,6 @@ impl<K: PartialEq + Hash, V> CHashMap<K, V> {
640684
// fuck im sleepy rn
641685
}
642686

643-
/// Get the number of entries in the hash table.
644-
///
645-
/// This is entirely atomic, and will not acquire any locks.
646-
pub fn len(&self) -> usize {
647-
self.len.load(ORDERING)
648-
}
649-
650-
/// Get the capacity of the hash table.
651-
///
652-
/// The capacity is equal to the number of entries the table can hold before reallocating.
653-
pub fn capacity(&self) -> usize {
654-
self.buckets() * MAX_LOAD_FACTOR_NUM / MAX_LOAD_FACTOR_DENOM
655-
}
656-
657-
/// Get the number of buckets of the hash table.
658-
///
659-
/// "Buckets" refers to the amount of potential entries in the inner table. It is different
660-
/// from capacity, in the sense that the map cannot hold this number of entries, since it needs
661-
/// to keep the load factor low.
662-
pub fn buckets(&self) -> usize {
663-
self.table.read().buckets.len()
664-
}
665-
666-
/// Is the hash table empty?
667-
pub fn is_empty(&self) -> bool {
668-
self.len() == 0
669-
}
670-
671687
/// Insert a **new** entry.
672688
///
673689
/// This inserts an entry, which the map does not already contain, into the table. If the entry

chashmap/src/tests.rs

+20
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,26 @@ fn alter_string() {
258258
assert_eq!(&*m.get(&1).unwrap(), "a");
259259
}
260260

261+
#[test]
262+
fn clear() {
263+
let m = CHashMap::new();
264+
assert!(m.insert(1, 2).is_none());
265+
assert!(m.insert(2, 4).is_none());
266+
assert_eq!(m.len(), 2);
267+
268+
let om = m.clear();
269+
assert_eq!(om.len(), 2);
270+
assert_eq!(*om.get(&1).unwrap(), 2);
271+
assert_eq!(*om.get(&2).unwrap(), 4);
272+
273+
assert!(m.is_empty());
274+
assert_eq!(m.len(), 0);
275+
276+
assert_eq!(m.get(&1), None);
277+
assert_eq!(m.get(&2), None);
278+
}
279+
280+
261281
thread_local! { static DROP_VECTOR: RefCell<Vec<isize>> = RefCell::new(Vec::new()) }
262282

263283
#[derive(Hash, PartialEq, Eq)]

0 commit comments

Comments
 (0)