fix: hash impl of Dict, Set

This commit is contained in:
Shunsuke Shibayama 2024-09-04 14:10:32 +09:00
parent a32da8e4a9
commit 4bc596af00
2 changed files with 15 additions and 17 deletions

View file

@ -8,6 +8,7 @@ use std::iter::FromIterator;
use std::ops::{Index, IndexMut};
use crate::fxhash::FxHashMap;
use crate::get_hash;
#[macro_export]
macro_rules! dict {
@ -34,10 +35,15 @@ impl<K: Hash + Eq, V: Hash + Eq> Eq for Dict<K, V> {}
impl<K: Hash, V: Hash> Hash for Dict<K, V> {
fn hash<H: Hasher>(&self, state: &mut H) {
let keys = self.dict.keys().collect::<Vec<_>>();
keys.hash(state);
let vals = self.dict.values().collect::<Vec<_>>();
vals.hash(state);
let mut v = self
.iter()
.map(|(key, val)| (get_hash(key), key, val))
.collect::<Vec<_>>();
v.sort_by_key(|(h, _, _)| *h);
for (_, key, val) in v.iter() {
key.hash(state);
val.hash(state);
}
}
}

View file

@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use crate::fxhash::FxHashSet;
use crate::{debug_fmt_iter, fmt_iter};
use crate::{debug_fmt_iter, fmt_iter, get_hash};
#[cfg(feature = "pylib")]
use pyo3::prelude::PyAnyMethods;
@ -46,14 +46,9 @@ where
}
}
// Use `fast_eq` for faster comparisons
impl<T: Hash + Eq> PartialEq for Set<T> {
fn eq(&self, other: &Set<T>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter()
.all(|l_key| other.iter().any(|r_key| l_key == r_key))
self.elems.eq(&other.elems)
}
}
@ -67,7 +62,9 @@ impl<T> Default for Set<T> {
impl<T: Hash> Hash for Set<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.elems.iter().collect::<Vec<_>>().hash(state);
let mut v = self.iter().map(get_hash).collect::<Vec<_>>();
v.sort();
v.hash(state);
}
}
@ -184,11 +181,6 @@ impl<T: Hash + Eq> Set<T> {
self.elems.iter().find(|&v| cmp(v.borrow(), value))
}
#[inline]
pub fn fast_eq(&self, other: &Set<T>) -> bool {
self.elems == other.elems
}
#[inline]
pub fn contains<Q>(&self, value: &Q) -> bool
where