Use portable hash function for CacheKey (#7533)

This commit is contained in:
Micha Reiser 2023-09-20 15:19:59 +02:00 committed by GitHub
parent bb4f7c681a
commit ca3c15858d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 41 deletions

7
Cargo.lock generated
View file

@ -2058,6 +2058,7 @@ dependencies = [
"itertools 0.11.0",
"regex",
"ruff_macros",
"seahash",
]
[[package]]
@ -2665,6 +2666,12 @@ dependencies = [
"untrusted",
]
[[package]]
name = "seahash"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "semver"
version = "1.0.18"

View file

@ -16,6 +16,7 @@ glob = { workspace = true }
globset = { workspace = true }
regex = { workspace = true }
filetime = { workspace = true }
seahash = "4.1.0"
[dev-dependencies]
ruff_macros = { path = "../ruff_macros" }

View file

@ -1,41 +1,13 @@
use std::borrow::Cow;
use std::collections::hash_map::DefaultHasher;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::num::NonZeroU8;
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use glob::Pattern;
use itertools::Itertools;
use regex::Regex;
#[derive(Clone, Debug, Default)]
pub struct CacheKeyHasher {
inner: DefaultHasher,
}
impl CacheKeyHasher {
pub fn new() -> Self {
Self {
inner: DefaultHasher::new(),
}
}
}
impl Deref for CacheKeyHasher {
type Target = DefaultHasher;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for CacheKeyHasher {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
use seahash::SeaHasher;
/// A type that be used as part of a cache key.
///
@ -255,14 +227,14 @@ impl_cache_key_tuple! { T B C D E F G H I J K L }
impl CacheKey for str {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.hash(&mut **state);
self.hash(&mut *state);
}
}
impl CacheKey for String {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.hash(&mut **state);
self.hash(&mut *state);
}
}
@ -360,14 +332,14 @@ impl<K: CacheKey + Ord, V: CacheKey> CacheKey for BTreeMap<K, V> {
impl CacheKey for Path {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.hash(&mut **state);
self.hash(&mut *state);
}
}
impl CacheKey for PathBuf {
#[inline]
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.hash(&mut **state);
self.as_path().cache_key(state);
}
}
@ -391,3 +363,88 @@ impl CacheKey for Pattern {
self.as_str().cache_key(state);
}
}
#[derive(Clone, Default)]
pub struct CacheKeyHasher {
inner: SeaHasher,
}
impl CacheKeyHasher {
pub fn new() -> Self {
Self {
inner: SeaHasher::new(),
}
}
}
impl Hasher for CacheKeyHasher {
#[inline]
fn finish(&self) -> u64 {
self.inner.finish()
}
#[inline]
fn write(&mut self, bytes: &[u8]) {
self.inner.write(bytes);
}
#[inline]
fn write_u8(&mut self, i: u8) {
self.inner.write_u8(i);
}
#[inline]
fn write_u16(&mut self, i: u16) {
self.inner.write_u16(i);
}
#[inline]
fn write_u32(&mut self, i: u32) {
self.inner.write_u32(i);
}
#[inline]
fn write_u64(&mut self, i: u64) {
self.inner.write_u64(i);
}
#[inline]
fn write_u128(&mut self, i: u128) {
self.inner.write_u128(i);
}
#[inline]
fn write_usize(&mut self, i: usize) {
self.inner.write_usize(i);
}
#[inline]
fn write_i8(&mut self, i: i8) {
self.inner.write_i8(i);
}
#[inline]
fn write_i16(&mut self, i: i16) {
self.inner.write_i16(i);
}
#[inline]
fn write_i32(&mut self, i: i32) {
self.inner.write_i32(i);
}
#[inline]
fn write_i64(&mut self, i: i64) {
self.inner.write_i64(i);
}
#[inline]
fn write_i128(&mut self, i: i128) {
self.inner.write_i128(i);
}
#[inline]
fn write_isize(&mut self, i: isize) {
self.inner.write_isize(i);
}
}

View file

@ -6,6 +6,6 @@ use crate::{CacheKey, CacheKeyHasher};
impl CacheKey for FileTime {
fn cache_key(&self, state: &mut CacheKeyHasher) {
self.hash(&mut **state);
self.hash(&mut *state);
}
}

View file

@ -1,4 +1,3 @@
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use ruff_cache::{CacheKey, CacheKeyHasher};
@ -29,7 +28,7 @@ fn unit_struct_cache_key() {
UnitStruct.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
UnitStruct.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());
@ -46,7 +45,7 @@ fn named_field_struct() {
named_fields.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
named_fields.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());
@ -60,7 +59,7 @@ fn unnamed_field_struct() {
unnamed_fields.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
unnamed_fields.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());
@ -73,7 +72,7 @@ fn enum_unit_variant() {
let variant = Enum::Unit;
variant.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
variant.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());
@ -89,7 +88,7 @@ fn enum_named_fields_variant() {
};
variant.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
variant.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());
@ -102,7 +101,7 @@ fn enum_unnamed_fields_variant() {
let variant = Enum::UnnamedFields("Hello".to_string(), "World".to_string());
variant.cache_key(&mut key);
let mut hash = DefaultHasher::new();
let mut hash = CacheKeyHasher::new();
variant.hash(&mut hash);
assert_eq!(hash.finish(), key.finish());