Use is_absent_and_set.

This commit is contained in:
Stephen Chung 2022-09-12 22:40:52 +08:00
parent 44219c732c
commit 08f6682d09
3 changed files with 17 additions and 8 deletions

View File

@ -268,9 +268,8 @@ impl Engine {
}; };
if let Some(f) = func { if let Some(f) = func {
if cache.filter.is_absent(hash) { if cache.filter.is_absent_and_set(hash) {
// Do not cache "one-hit wonders" // Do not cache "one-hit wonders"
cache.filter.mark(hash);
local_entry = CallableFunction::from_fn_builtin(f); local_entry = CallableFunction::from_fn_builtin(f);
&local_entry &local_entry
} else { } else {

View File

@ -237,9 +237,8 @@ impl Engine {
func: f.clone(), func: f.clone(),
source: s.map(|s| Box::new(s.into())), source: s.map(|s| Box::new(s.into())),
}); });
return if cache.filter.is_absent(hash) { return if cache.filter.is_absent_and_set(hash) {
// Do not cache "one-hit wonders" // Do not cache "one-hit wonders"
cache.filter.mark(hash);
*local_entry = new_entry; *local_entry = new_entry;
local_entry.as_ref() local_entry.as_ref()
} else { } else {
@ -299,9 +298,8 @@ impl Engine {
} }
}); });
return if cache.filter.is_absent(hash) { return if cache.filter.is_absent_and_set(hash) {
// Do not cache "one-hit wonders" // Do not cache "one-hit wonders"
cache.filter.mark(hash);
*local_entry = builtin; *local_entry = builtin;
local_entry.as_ref() local_entry.as_ref()
} else { } else {

View File

@ -23,6 +23,7 @@ pub struct BloomFilterU64([usize; SIZE]);
impl BloomFilterU64 { impl BloomFilterU64 {
/// Get the bit position of a `u64` hash value. /// Get the bit position of a `u64` hash value.
#[inline(always)] #[inline(always)]
#[must_use]
const fn calc_hash(value: u64) -> (usize, usize) { const fn calc_hash(value: u64) -> (usize, usize) {
let hash = (value & 0x00ff) as usize; let hash = (value & 0x00ff) as usize;
(hash / 64, 0x01 << (hash % 64)) (hash / 64, 0x01 << (hash % 64))
@ -37,7 +38,7 @@ impl BloomFilterU64 {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.iter().all(|&v| v == 0) self.0 == [0; SIZE]
} }
/// Clear this [`BloomFilterU64`]. /// Clear this [`BloomFilterU64`].
#[inline(always)] #[inline(always)]
@ -46,7 +47,7 @@ impl BloomFilterU64 {
self self
} }
/// Mark a `u64` hash into this [`BloomFilterU64`]. /// Mark a `u64` hash into this [`BloomFilterU64`].
#[inline(always)] #[inline]
pub fn mark(&mut self, hash: u64) -> &mut Self { pub fn mark(&mut self, hash: u64) -> &mut Self {
let (offset, mask) = Self::calc_hash(hash); let (offset, mask) = Self::calc_hash(hash);
self.0[offset] |= mask; self.0[offset] |= mask;
@ -54,10 +55,21 @@ impl BloomFilterU64 {
} }
/// Is a `u64` hash definitely absent from this [`BloomFilterU64`]? /// Is a `u64` hash definitely absent from this [`BloomFilterU64`]?
#[inline] #[inline]
#[must_use]
pub const fn is_absent(&self, hash: u64) -> bool { pub const fn is_absent(&self, hash: u64) -> bool {
let (offset, mask) = Self::calc_hash(hash); let (offset, mask) = Self::calc_hash(hash);
(self.0[offset] & mask) == 0 (self.0[offset] & mask) == 0
} }
/// If a `u64` hash is absent from this [`BloomFilterU64`], return `true` and then mark it.
/// Otherwise return `false`.
#[inline]
#[must_use]
pub fn is_absent_and_set(&mut self, hash: u64) -> bool {
let (offset, mask) = Self::calc_hash(hash);
let result = (self.0[offset] & mask) == 0;
self.0[offset] |= mask;
result
}
} }
impl Add for &BloomFilterU64 { impl Add for &BloomFilterU64 {