Speed up static hashing default case.
This commit is contained in:
parent
a07eb65f02
commit
1b248b5af7
@ -39,7 +39,7 @@ New features
|
|||||||
|
|
||||||
### Static hashing
|
### Static hashing
|
||||||
|
|
||||||
* It is now possible to specify a fixed _seed_ for use with the `ahash` hasher, via a static function `rhai::config::hashing::set_ahash_seed` or an environment variable, in order to force static (i.e. deterministic) hashes for function signatures.
|
* It is now possible to specify a fixed _seed_ for use with the `ahash` hasher, via a static function `rhai::config::hashing::set_ahash_seed` or an environment variable (`RHAI_AHASH_SEED`), in order to force static (i.e. deterministic) hashes for function signatures.
|
||||||
* This is necessary when using Rhai across shared-library boundaries.
|
* This is necessary when using Rhai across shared-library boundaries.
|
||||||
* A build script is used to extract the environment variable (`RHAI_AHASH_SEED`, if any) and splice it into the source code before compilation.
|
* A build script is used to extract the environment variable (`RHAI_AHASH_SEED`, if any) and splice it into the source code before compilation.
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ fn hokmalock(address: usize) -> &'static HokmaLock {
|
|||||||
&RECORDS[address % LEN]
|
&RECORDS[address % LEN]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safety: lol, there is a reason its called "SusLock<T>"
|
// Safety: lol, there is a reason its called `SusLock<T>`
|
||||||
#[must_use]
|
#[must_use]
|
||||||
struct SusLock<T>
|
struct SusLock<T>
|
||||||
where
|
where
|
||||||
@ -118,36 +118,39 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_initialized(&self) -> bool {
|
||||||
|
self.initialized.load(Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get(&self) -> Option<&'static T> {
|
pub fn get(&self) -> Option<&'static T> {
|
||||||
if self.initialized.load(Ordering::SeqCst) {
|
if self.initialized.load(Ordering::SeqCst) {
|
||||||
let hokma = hokmalock(unsafe { mem::transmute(self.data.get()) });
|
let hokma = hokmalock(unsafe { mem::transmute(self.data.get()) });
|
||||||
// we forgo the optimistic read, because we don't really care
|
// we forgo the optimistic read, because we don't really care
|
||||||
let guard = hokma.write();
|
let guard = hokma.write();
|
||||||
let val = {
|
|
||||||
let cast: *const T = self.data.get().cast();
|
let cast: *const T = self.data.get().cast();
|
||||||
unsafe { mem::transmute::<*const T, &'static T>(cast) }
|
let val = unsafe { mem::transmute::<*const T, &'static T>(cast) };
|
||||||
};
|
|
||||||
guard.the_price_of_silence();
|
guard.the_price_of_silence();
|
||||||
Some(val)
|
Some(val)
|
||||||
} else {
|
} else {
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_or_init(&self, f: impl FnOnce() -> T) -> Option<&'static T> {
|
pub fn get_or_init(&self, f: impl FnOnce() -> T) -> &'static T {
|
||||||
if !self.initialized.load(Ordering::SeqCst) {
|
if !self.initialized.load(Ordering::SeqCst) {
|
||||||
let value = f();
|
|
||||||
self.initialized.store(true, Ordering::SeqCst);
|
self.initialized.store(true, Ordering::SeqCst);
|
||||||
let hokma = hokmalock(unsafe { mem::transmute(self.data.get()) });
|
let hokma = hokmalock(unsafe { mem::transmute(self.data.get()) });
|
||||||
hokma.write();
|
hokma.write();
|
||||||
unsafe {
|
unsafe {
|
||||||
self.data.get().write(MaybeUninit::new(value));
|
self.data.get().write(MaybeUninit::new(f()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get()
|
self.get().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&self, value: T) -> Result<(), T> {
|
pub fn set(&self, value: T) -> Result<(), T> {
|
||||||
@ -217,10 +220,9 @@ pub fn set_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_ahash_seed() -> &'static Option<[u64; 4]> {
|
pub fn get_ahash_seed() -> &'static Option<[u64; 4]> {
|
||||||
const NONE: &'static Option<[u64; 4]> = &None;
|
if !AHASH_SEED.is_initialized() {
|
||||||
|
return &hashing_env::AHASH_SEED;
|
||||||
|
}
|
||||||
|
|
||||||
match AHASH_SEED.get_or_init(|| hashing_env::AHASH_SEED) {
|
AHASH_SEED.get().unwrap_or(&hashing_env::AHASH_SEED)
|
||||||
Some(ash) => ash,
|
|
||||||
None => NONE,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -74,12 +74,12 @@ impl BuildHasher for StraightHasherBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create an instance of the default hasher.
|
/// Create an instance of the default hasher.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_hasher() -> ahash::AHasher {
|
pub fn get_hasher() -> ahash::AHasher {
|
||||||
match config::hashing::get_ahash_seed() {
|
match config::hashing::get_ahash_seed() {
|
||||||
Some([seed1, seed2, seed3, seed4]) if seed1 | seed2 | seed3 | seed4 != 0 => {
|
&Some([seed1, seed2, seed3, seed4]) if (seed1 | seed2 | seed3 | seed4) != 0 => {
|
||||||
ahash::RandomState::with_seeds(*seed1, *seed2, *seed3, *seed4).build_hasher()
|
ahash::RandomState::with_seeds(seed1, seed2, seed3, seed4).build_hasher()
|
||||||
}
|
}
|
||||||
_ => ahash::AHasher::default(),
|
_ => ahash::AHasher::default(),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user