Skip to content

Commit

Permalink
auto merge of #13088 : thestinger/rust/hashmap, r=cmr
Browse files Browse the repository at this point in the history
Closes #5283
  • Loading branch information
bors committed Mar 23, 2014
2 parents 3d9fdf7 + 3829ac2 commit 2ddb605
Show file tree
Hide file tree
Showing 28 changed files with 203 additions and 180 deletions.
2 changes: 1 addition & 1 deletion src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use std::num::Bitwise;

#[deriving(Clone, Eq, Hash, Show)]
#[deriving(Clone, Eq, TotalEq, Hash, Show)]
/// A specialized Set implementation to use enum types.
pub struct EnumSet<E> {
// We must maintain the invariant that no bits are set
Expand Down
57 changes: 27 additions & 30 deletions src/libcollections/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use std::container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
use std::clone::Clone;
use std::cmp::{Eq, Equiv, max};
use std::cmp::{Eq, TotalEq, Equiv, max};
use std::default::Default;
use std::fmt;
use std::fmt::Show;
Expand Down Expand Up @@ -140,6 +140,7 @@ mod table {
}

/// A hash that is not zero, since we use that to represent empty buckets.
#[deriving(Eq)]
pub struct SafeHash {
priv hash: u64,
}
Expand All @@ -149,10 +150,6 @@ mod table {
pub fn inspect(&self) -> u64 { self.hash }
}

impl Eq for SafeHash {
fn eq(&self, other: &SafeHash) -> bool { self.hash == other.hash }
}

/// We need to remove hashes of 0. That's reserved for empty buckets.
/// This function wraps up `hash_keyed` to be the only way outside this
/// module to generate a SafeHash.
Expand Down Expand Up @@ -698,7 +695,7 @@ fn grow_at(capacity: uint, load_factor: Fraction) -> uint {
fraction_mul(capacity, load_factor)
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// Get the number of elements which will force the capacity to shrink.
/// When size == self.shrink_at(), we halve the capacity.
fn shrink_at(&self) -> uint {
Expand Down Expand Up @@ -799,12 +796,12 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
}
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
/// Return the number of elements in the map
fn len(&self) -> uint { self.table.size() }
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
/// Clear the map, removing all key-value pairs.
fn clear(&mut self) {
self.minimum_capacity = self.table.size();
Expand All @@ -819,7 +816,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
}


impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
self.search(k).map(|idx| {
let (_, v) = self.table.read(&idx);
Expand All @@ -832,7 +829,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
}
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
match self.search(k) {
None => None,
Expand Down Expand Up @@ -969,7 +966,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H>
}
}

impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
impl<K: Hash + TotalEq, V> HashMap<K, V, sip::SipHasher> {
/// Create an empty HashMap.
pub fn new() -> HashMap<K, V, sip::SipHasher> {
HashMap::with_capacity(INITIAL_CAPACITY)
Expand All @@ -984,7 +981,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
}
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
}
Expand Down Expand Up @@ -1296,7 +1293,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
}
}

impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
/// Like `find`, but returns a copy of the value.
pub fn find_copy(&self, k: &K) -> Option<V> {
self.find(k).map(|v| (*v).clone())
Expand All @@ -1308,7 +1305,7 @@ impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
}
}

impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {
fn eq(&self, other: &HashMap<K, V, H>) -> bool {
if self.len() != other.len() { return false; }

Expand All @@ -1321,7 +1318,7 @@ impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {
}
}

impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, r"\{"));

Expand All @@ -1334,7 +1331,7 @@ impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H>
}
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
fn default() -> HashMap<K, V, H> {
HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, Default::default())
}
Expand All @@ -1358,7 +1355,7 @@ pub type Keys<'a, K, V> =
pub type Values<'a, K, V> =
iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;

impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V, H> {
let (lower, _) = iter.size_hint();
let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
Expand All @@ -1367,7 +1364,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for Has
}
}

impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
impl<K: TotalEq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
for (k, v) in *iter {
self.insert(k, v);
Expand All @@ -1391,7 +1388,7 @@ pub struct HashSet<T, H = sip::SipHasher> {
priv map: HashMap<T, (), H>
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {
// FIXME #11998: Since the value is a (), and `find` returns a Some(&()),
// we trigger #11998 when matching on it. I've fallen back to manual
// iteration until this is fixed.
Expand All @@ -1402,17 +1399,17 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {
}
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
/// Return the number of elements in the set
fn len(&self) -> uint { self.map.len() }
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
/// Clear the set, removing all values.
fn clear(&mut self) { self.map.clear() }
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool { self.map.search(value).is_some() }

Expand All @@ -1433,7 +1430,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
}
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
Expand All @@ -1443,7 +1440,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}

impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
impl<T: Hash + TotalEq> HashSet<T, sip::SipHasher> {
/// Create an empty HashSet
pub fn new() -> HashSet<T, sip::SipHasher> {
HashSet::with_capacity(INITIAL_CAPACITY)
Expand All @@ -1456,7 +1453,7 @@ impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
}
}

impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
pub fn with_hasher(hasher: H) -> HashSet<T, H> {
HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
}
Expand Down Expand Up @@ -1529,7 +1526,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {

}

impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
impl<T: TotalEq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, r"\{"));

Expand All @@ -1542,7 +1539,7 @@ impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
}
}

impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
fn from_iterator<I: Iterator<T>>(iter: &mut I) -> HashSet<T, H> {
let (lower, _) = iter.size_hint();
let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
Expand All @@ -1551,15 +1548,15 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T,
}
}

impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
impl<T: TotalEq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
fn extend<I: Iterator<T>>(&mut self, iter: &mut I) {
for k in *iter {
self.insert(k);
}
}
}

impl<T: Eq + Hash> Default for HashSet<T, sip::SipHasher> {
impl<T: TotalEq + Hash> Default for HashSet<T, sip::SipHasher> {
fn default() -> HashSet<T> { HashSet::new() }
}

Expand Down Expand Up @@ -1601,7 +1598,7 @@ mod test_map {

local_data_key!(drop_vector: vec::Vec<int>)

#[deriving(Hash, Eq)]
#[deriving(Hash, Eq, TotalEq)]
struct Dropable {
k: int
}
Expand Down
10 changes: 6 additions & 4 deletions src/libcollections/lru_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ impl<K: Eq> Eq for KeyRef<K> {
}
}

impl<K: TotalEq> TotalEq for KeyRef<K> {}

impl<K, V> LruEntry<K, V> {
fn new() -> LruEntry<K, V> {
LruEntry {
Expand All @@ -94,7 +96,7 @@ impl<K, V> LruEntry<K, V> {
}
}

impl<K: Hash + Eq, V> LruCache<K, V> {
impl<K: Hash + TotalEq, V> LruCache<K, V> {
/// Create an LRU Cache that holds at most `capacity` items.
pub fn new(capacity: uint) -> LruCache<K, V> {
let cache = LruCache {
Expand Down Expand Up @@ -218,7 +220,7 @@ impl<K: Hash + Eq, V> LruCache<K, V> {
}
}

impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
impl<A: fmt::Show + Hash + TotalEq, B: fmt::Show> fmt::Show for LruCache<A, B> {
/// Return a string that lists the key-value pairs from most-recently
/// used to least-recently used.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -247,14 +249,14 @@ impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
}
}

impl<K: Hash + Eq, V> Container for LruCache<K, V> {
impl<K: Hash + TotalEq, V> Container for LruCache<K, V> {
/// Return the number of key-value pairs in the cache.
fn len(&self) -> uint {
self.map.len()
}
}

impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
impl<K: Hash + TotalEq, V> Mutable for LruCache<K, V> {
/// Clear the cache of all key-value pairs.
fn clear(&mut self) {
self.map.clear();
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ pub struct BorrowStats {
//
// Note that there is no entry with derefs:3---the type of that expression
// is T, which is not a box.
#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub struct root_map_key {
id: ast::NodeId,
derefs: uint
Expand Down Expand Up @@ -243,13 +243,13 @@ pub enum LoanCause {
RefBinding,
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum LoanPath {
LpVar(ast::NodeId), // `x` in doc.rs
LpExtend(@LoanPath, mc::MutabilityCategory, LoanPathElem)
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum LoanPathElem {
LpDeref(mc::PointerKind), // `*LV` in doc.rs
LpInterior(mc::InteriorKind) // `LV.f` in doc.rs
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub struct CopiedUpvar {
}

// different kinds of pointers:
#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum PointerKind {
OwnedPtr,
GcPtr,
Expand All @@ -105,26 +105,26 @@ pub enum PointerKind {

// We use the term "interior" to mean "something reachable from the
// base without a pointer dereference", e.g. a field
#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum InteriorKind {
InteriorField(FieldName),
InteriorElement(ElementKind),
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum FieldName {
NamedField(ast::Name),
PositionalField(uint)
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum ElementKind {
VecElement,
StrElement,
OtherElement,
}

#[deriving(Eq, Hash, Show)]
#[deriving(Eq, TotalEq, Hash, Show)]
pub enum MutabilityCategory {
McImmutable, // Immutable.
McDeclared, // Directly declared as mutable.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ enum PatternBindingMode {
ArgumentIrrefutableMode,
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
enum Namespace {
TypeNS,
ValueNS
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ pub fn is_null(val: ValueRef) -> bool {
}

// Used to identify cached monomorphized functions and vtables
#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum mono_param_id {
mono_precise(ty::t, Option<@Vec<mono_id> >),
mono_any,
Expand All @@ -720,7 +720,7 @@ pub enum mono_param_id {
datum::RvalueMode),
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub enum MonoDataClass {
MonoBits, // Anything not treated differently from arbitrary integer data
MonoNonNull, // Non-null pointers (used for optional-pointer optimization)
Expand All @@ -742,7 +742,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
}
}

#[deriving(Eq, Hash)]
#[deriving(Eq, TotalEq, Hash)]
pub struct mono_id_ {
def: ast::DefId,
params: Vec<mono_param_id> }
Expand Down
Loading

0 comments on commit 2ddb605

Please sign in to comment.