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 cache.filter.is_absent(hash) {
if cache.filter.is_absent_and_set(hash) {
// Do not cache "one-hit wonders"
cache.filter.mark(hash);
local_entry = CallableFunction::from_fn_builtin(f);
&local_entry
} else {

View File

@ -237,9 +237,8 @@ impl Engine {
func: f.clone(),
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"
cache.filter.mark(hash);
*local_entry = new_entry;
local_entry.as_ref()
} 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"
cache.filter.mark(hash);
*local_entry = builtin;
local_entry.as_ref()
} else {

View File

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