Skip to content

Commit ea43694

Browse files
committed
ahash instead of wyhash
1 parent 7396f0b commit ea43694

5 files changed

Lines changed: 53 additions & 22 deletions

File tree

Cargo.lock

Lines changed: 35 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ classifier = [
5151
]
5252

5353
[dependencies]
54+
ahash = { version = "0.7", default_features = false }
5455
associative-cache = { version = "1" }
5556
bytecount = { version = "^0.6.2", default_features = false, features = ["generic-simd", "runtime-dispatch-simd"] }
5657
encoding_rs = { version = "0.8", default_features = false }
@@ -62,7 +63,6 @@ ryu = { version = "1" }
6263
serde = { version = "1", default_features = false }
6364
serde_json = { path = "./json", default_features = false, features = ["std"] }
6465
smallvec = { version = "^1.6", default_features = false, features = ["const_generics", "union", "specialization", "write"] }
65-
wyhash = { version = "0.5" }
6666

6767
[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "i686", target_arch = "armv7"))'.dependencies]
6868
encoding_rs = { version = "0.8", default_features = false, features = ["simd-accel"] }

src/deserialize/cache.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

3+
use crate::typeref::*;
4+
use ahash::CallHasher;
35
use associative_cache::replacement::RoundRobinReplacement;
46
use associative_cache::*;
57
use once_cell::unsync::OnceCell;
@@ -37,3 +39,7 @@ pub type KeyMap =
3739
AssociativeCache<u64, CachedKey, Capacity512, HashDirectMapped, RoundRobinReplacement>;
3840

3941
pub static mut KEY_MAP: OnceCell<KeyMap> = OnceCell::new();
42+
43+
pub fn cache_hash(key: &[u8]) -> u64 {
44+
<[u8]>::get_hash(&key, unsafe { &*HASH_BUILDER })
45+
}

src/deserialize/deserializer.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::borrow::Cow;
1111
use std::fmt;
1212
use std::os::raw::c_char;
1313
use std::ptr::NonNull;
14-
use wyhash::wyhash;
1514

1615
pub fn deserialize(
1716
ptr: *mut pyo3::ffi::PyObject,
@@ -173,11 +172,11 @@ impl<'de> Visitor<'de> for JsonValue {
173172
{
174173
let dict_ptr = ffi!(PyDict_New());
175174
while let Some(key) = map.next_key::<Cow<str>>()? {
175+
let value = map.next_value_seed(self)?;
176176
let pykey: *mut pyo3::ffi::PyObject;
177177
let pyhash: pyo3::ffi::Py_hash_t;
178-
let value = map.next_value_seed(self)?;
179178
if likely!(key.len() <= 64) {
180-
let hash = unsafe { wyhash(key.as_bytes(), HASH_SEED) };
179+
let hash = cache_hash(key.as_bytes());
181180
{
182181
let map = unsafe {
183182
KEY_MAP

src/typeref.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

3+
use ahash::RandomState;
34
use once_cell::unsync::Lazy;
45
use pyo3::ffi::*;
56
use std::os::raw::c_char;
@@ -17,7 +18,6 @@ pub struct NumpyTypes {
1718
pub uint32: *mut PyTypeObject,
1819
pub uint8: *mut PyTypeObject,
1920
}
20-
pub static mut HASH_SEED: u64 = 0;
2121

2222
pub static mut NONE: *mut PyObject = 0 as *mut PyObject;
2323
pub static mut TRUE: *mut PyObject = 0 as *mut PyObject;
@@ -57,6 +57,14 @@ pub static mut VALUE_STR: *mut PyObject = 0 as *mut PyObject;
5757
pub static mut STR_HASH_FUNCTION: Option<hashfunc> = None;
5858
pub static mut DEFAULT: *mut PyObject = 0 as *mut PyObject;
5959
pub static mut OPTION: *mut PyObject = 0 as *mut PyObject;
60+
pub static mut HASH_BUILDER: Lazy<ahash::RandomState> = Lazy::new(|| unsafe {
61+
RandomState::with_seeds(
62+
VALUE_STR as u64,
63+
DICT_TYPE as u64,
64+
STR_TYPE as u64,
65+
BYTES_TYPE as u64,
66+
)
67+
});
6068

6169
#[allow(non_upper_case_globals)]
6270
pub static mut JsonEncodeError: *mut PyObject = 0 as *mut PyObject;
@@ -114,7 +122,6 @@ pub fn init_typerefs() {
114122
ARRAY_STRUCT_STR =
115123
pyo3::ffi::PyUnicode_InternFromString("__array_struct__\0".as_ptr() as *const c_char);
116124
VALUE_STR = pyo3::ffi::PyUnicode_InternFromString("value\0".as_ptr() as *const c_char);
117-
HASH_SEED = (VALUE_STR as u64).wrapping_mul(DICT_TYPE as u64);
118125
DEFAULT = PyUnicode_InternFromString("default\0".as_ptr() as *const c_char);
119126
OPTION = PyUnicode_InternFromString("option\0".as_ptr() as *const c_char);
120127
JsonEncodeError = pyo3::ffi::PyExc_TypeError;

0 commit comments

Comments
 (0)