diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2013-08-01 18:11:25 +1000 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2013-08-03 21:00:32 +1000 |
| commit | c852a5bb681d08796959818470ed5233bfa69edc (patch) | |
| tree | d4f27652e955076c7bc8c0030b1580b24c872489 /src/libstd | |
| parent | 39fafd655a85a2af9cddf59b70a687b44570fb6f (diff) | |
| download | rust-c852a5bb681d08796959818470ed5233bfa69edc.tar.gz rust-c852a5bb681d08796959818470ed5233bfa69edc.zip | |
std: expose the keyed HashMap constructor, for runtime-less use.
The `new` constructor uses the task-local RNG to retrieve seeds for the two key values, which requires the runtime. Exposing a constructor that takes the keys directly allows HashMaps to be used in programs that wish to avoid the runtime.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/hashmap.rs | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index e7d51106c58..4de5d316fc0 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -61,27 +61,7 @@ enum SearchResult { #[inline] fn resize_at(capacity: uint) -> uint { - ((capacity as float) * 3. / 4.) as uint -} - -/// Creates a new hash map with the specified capacity. -pub fn linear_map_with_capacity<K:Eq + Hash,V>( - initial_capacity: uint) -> HashMap<K, V> { - let mut r = rand::task_rng(); - linear_map_with_capacity_and_keys(r.gen(), r.gen(), - initial_capacity) -} - -fn linear_map_with_capacity_and_keys<K:Eq + Hash,V>( - k0: u64, k1: u64, - initial_capacity: uint) -> HashMap<K, V> { - let cap = num::max(INITIAL_CAPACITY, initial_capacity); - HashMap { - k0: k0, k1: k1, - resize_at: resize_at(cap), - size: 0, - buckets: vec::from_fn(cap, |_| None) - } + (capacity * 3) / 4 } impl<K:Hash + Eq,V> HashMap<K, V> { @@ -352,10 +332,28 @@ impl<K: Hash + Eq, V> HashMap<K, V> { HashMap::with_capacity(INITIAL_CAPACITY) } - /// Create an empty HashMap with space for at least `n` elements in - /// the hash table. + /// Create an empty HashMap with space for at least `capacity` + /// elements in the hash table. pub fn with_capacity(capacity: uint) -> HashMap<K, V> { - linear_map_with_capacity(capacity) + let mut r = rand::task_rng(); + HashMap::with_capacity_and_keys(r.gen(), r.gen(), capacity) + } + + /// Create an empty HashMap with space for at least `capacity` + /// elements, using `k0` and `k1` as the keys. + /// + /// Warning: `k0` and `k1` are normally randomly generated, and + /// are designed to allow HashMaps to be resistant to attacks that + /// cause many collisions and very poor performance. Setting them + /// manually using this function can expose a DoS attack vector. + pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashMap<K, V> { + let cap = num::max(INITIAL_CAPACITY, capacity); + HashMap { + k0: k0, k1: k1, + resize_at: resize_at(cap), + size: 0, + buckets: vec::from_fn(cap, |_| None) + } } /// Reserve space for at least `n` elements in the hash table. @@ -844,7 +842,7 @@ mod test_map { #[test] fn test_insert_conflicts() { - let mut m = linear_map_with_capacity(4); + let mut m = HashMap::with_capacity(4); assert!(m.insert(1, 2)); assert!(m.insert(5, 3)); assert!(m.insert(9, 4)); @@ -855,7 +853,7 @@ mod test_map { #[test] fn test_conflict_remove() { - let mut m = linear_map_with_capacity(4); + let mut m = HashMap::with_capacity(4); assert!(m.insert(1, 2)); assert!(m.insert(5, 3)); assert!(m.insert(9, 4)); @@ -866,7 +864,7 @@ mod test_map { #[test] fn test_is_empty() { - let mut m = linear_map_with_capacity(4); + let mut m = HashMap::with_capacity(4); assert!(m.insert(1, 2)); assert!(!m.is_empty()); assert!(m.remove(&1)); @@ -927,7 +925,7 @@ mod test_map { #[test] fn test_iterate() { - let mut m = linear_map_with_capacity(4); + let mut m = HashMap::with_capacity(4); foreach i in range(0u, 32) { assert!(m.insert(i, i*2)); } |
