mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 00:43:50 +00:00
optimize Hash for Path
Hashing does not have to use the whole Components parsing machinery because we only need it to match the normalizations that Components does. * stripping redundant separators -> skipping separators * stripping redundant '.' directories -> skipping '.' following after a separator That's all it takes. And instead of hashing individual slices for each component we feed the bytes directly into the hasher which avoids hashing the length of each component in addition to its contents.
This commit is contained in:
parent
82b4544ddc
commit
a083dd653a
@ -2873,9 +2873,35 @@ impl cmp::PartialEq for Path {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Hash for Path {
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
for component in self.components() {
|
||||
component.hash(h);
|
||||
let bytes = self.as_u8_slice();
|
||||
|
||||
let mut component_start = 0;
|
||||
let mut bytes_hashed = 0;
|
||||
|
||||
for i in 0..bytes.len() {
|
||||
if is_sep_byte(bytes[i]) {
|
||||
if i > component_start {
|
||||
let to_hash = &bytes[component_start..i];
|
||||
h.write(to_hash);
|
||||
bytes_hashed += to_hash.len();
|
||||
}
|
||||
|
||||
// skip over separator and optionally a following CurDir item
|
||||
// since components() would normalize these away
|
||||
component_start = i + match bytes[i..] {
|
||||
[_, b'.', b'/', ..] | [_, b'.'] => 2,
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if component_start < bytes.len() {
|
||||
let to_hash = &bytes[component_start..];
|
||||
h.write(to_hash);
|
||||
bytes_hashed += to_hash.len();
|
||||
}
|
||||
|
||||
h.write_usize(bytes_hashed);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user