Fix sync build.
This commit is contained in:
parent
d1913edf3c
commit
b4ef89b596
@ -1,5 +1,6 @@
|
|||||||
//! Module that defines the public compilation API of [`Engine`].
|
//! Module that defines the public compilation API of [`Engine`].
|
||||||
|
|
||||||
|
use crate::func::native::locked_write;
|
||||||
use crate::parser::{ParseResult, ParseState};
|
use crate::parser::{ParseResult, ParseState};
|
||||||
use crate::{Engine, OptimizationLevel, Scope, AST};
|
use crate::{Engine, OptimizationLevel, Scope, AST};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
@ -221,7 +222,7 @@ impl Engine {
|
|||||||
scripts.as_ref(),
|
scripts.as_ref(),
|
||||||
self.token_mapper.as_ref().map(<_>::as_ref),
|
self.token_mapper.as_ref().map(<_>::as_ref),
|
||||||
);
|
);
|
||||||
let interned_strings = &mut *self.interned_strings.borrow_mut();
|
let interned_strings = &mut *locked_write(&self.interned_strings);
|
||||||
let mut state = ParseState::new(self, scope, interned_strings, tokenizer_control);
|
let mut state = ParseState::new(self, scope, interned_strings, tokenizer_control);
|
||||||
let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
@ -295,7 +296,7 @@ impl Engine {
|
|||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
|
|
||||||
let mut peekable = stream.peekable();
|
let mut peekable = stream.peekable();
|
||||||
let interned_strings = &mut *self.interned_strings.borrow_mut();
|
let interned_strings = &mut *locked_write(&self.interned_strings);
|
||||||
let mut state = ParseState::new(self, scope, interned_strings, tokenizer_control);
|
let mut state = ParseState::new(self, scope, interned_strings, tokenizer_control);
|
||||||
self.parse_global_expr(&mut peekable, &mut state, |_| {}, self.optimization_level)
|
self.parse_global_expr(&mut peekable, &mut state, |_| {}, self.optimization_level)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Module that defines the public evaluation API of [`Engine`].
|
//! Module that defines the public evaluation API of [`Engine`].
|
||||||
|
|
||||||
use crate::eval::{Caches, GlobalRuntimeState};
|
use crate::eval::{Caches, GlobalRuntimeState};
|
||||||
|
use crate::func::native::locked_write;
|
||||||
use crate::parser::ParseState;
|
use crate::parser::ParseState;
|
||||||
use crate::types::dynamic::Variant;
|
use crate::types::dynamic::Variant;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -118,7 +119,7 @@ impl Engine {
|
|||||||
) -> RhaiResultOf<T> {
|
) -> RhaiResultOf<T> {
|
||||||
let scripts = [script];
|
let scripts = [script];
|
||||||
let ast = {
|
let ast = {
|
||||||
let interned_strings = &mut *self.interned_strings.borrow_mut();
|
let interned_strings = &mut *locked_write(&self.interned_strings);
|
||||||
|
|
||||||
let (stream, tokenizer_control) =
|
let (stream, tokenizer_control) =
|
||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Module that defines JSON manipulation functions for [`Engine`].
|
//! Module that defines JSON manipulation functions for [`Engine`].
|
||||||
#![cfg(not(feature = "no_object"))]
|
#![cfg(not(feature = "no_object"))]
|
||||||
|
|
||||||
|
use crate::func::native::locked_write;
|
||||||
use crate::parser::{ParseSettingFlags, ParseState};
|
use crate::parser::{ParseSettingFlags, ParseState};
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope};
|
use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope};
|
||||||
@ -118,7 +119,7 @@ impl Engine {
|
|||||||
|
|
||||||
let ast = {
|
let ast = {
|
||||||
let scope = Scope::new();
|
let scope = Scope::new();
|
||||||
let interned_strings = &mut *self.interned_strings.borrow_mut();
|
let interned_strings = &mut *locked_write(&self.interned_strings);
|
||||||
let mut state = ParseState::new(self, &scope, interned_strings, tokenizer_control);
|
let mut state = ParseState::new(self, &scope, interned_strings, tokenizer_control);
|
||||||
|
|
||||||
self.parse_global_expr(
|
self.parse_global_expr(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Module that defines the public evaluation API of [`Engine`].
|
//! Module that defines the public evaluation API of [`Engine`].
|
||||||
|
|
||||||
use crate::eval::{Caches, GlobalRuntimeState};
|
use crate::eval::{Caches, GlobalRuntimeState};
|
||||||
|
use crate::func::native::locked_write;
|
||||||
use crate::parser::ParseState;
|
use crate::parser::ParseState;
|
||||||
use crate::{Engine, RhaiResultOf, Scope, AST};
|
use crate::{Engine, RhaiResultOf, Scope, AST};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
@ -57,7 +58,7 @@ impl Engine {
|
|||||||
pub fn run_with_scope(&self, scope: &mut Scope, script: &str) -> RhaiResultOf<()> {
|
pub fn run_with_scope(&self, scope: &mut Scope, script: &str) -> RhaiResultOf<()> {
|
||||||
let scripts = [script];
|
let scripts = [script];
|
||||||
let ast = {
|
let ast = {
|
||||||
let interned_strings = &mut *self.interned_strings.borrow_mut();
|
let interned_strings = &mut *locked_write(&self.interned_strings);
|
||||||
|
|
||||||
let (stream, tokenizer_control) =
|
let (stream, tokenizer_control) =
|
||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
|
@ -51,7 +51,7 @@ pub struct ParseState<'e, 's> {
|
|||||||
pub tokenizer_control: TokenizerControl,
|
pub tokenizer_control: TokenizerControl,
|
||||||
/// Controls whether parsing of an expression should stop given the next token.
|
/// Controls whether parsing of an expression should stop given the next token.
|
||||||
pub expr_filter: fn(&Token) -> bool,
|
pub expr_filter: fn(&Token) -> bool,
|
||||||
/// String interners.
|
/// Strings interner.
|
||||||
interned_strings: &'s mut StringsInterner,
|
interned_strings: &'s mut StringsInterner,
|
||||||
/// External [scope][Scope] with constants.
|
/// External [scope][Scope] with constants.
|
||||||
pub scope: &'e Scope<'e>,
|
pub scope: &'e Scope<'e>,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use super::BloomFilterU64;
|
use super::BloomFilterU64;
|
||||||
use crate::func::{hashing::get_hasher, StraightHashMap};
|
use crate::func::{hashing::get_hasher, StraightHashMap};
|
||||||
use crate::ImmutableString;
|
use crate::ImmutableString;
|
||||||
|
use ahash::HashMapExt;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use hashbrown::hash_map::Entry;
|
use hashbrown::hash_map::Entry;
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
@ -26,14 +27,10 @@ pub const MAX_STRING_LEN: usize = 24;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct StringsInterner {
|
pub struct StringsInterner {
|
||||||
/// Maximum number of strings interned.
|
|
||||||
pub capacity: usize,
|
|
||||||
/// Maximum string length.
|
|
||||||
pub max_string_len: usize,
|
|
||||||
/// Cached strings.
|
/// Cached strings.
|
||||||
cache: StraightHashMap<ImmutableString>,
|
cache: StraightHashMap<ImmutableString>,
|
||||||
/// Bloom filter to avoid caching "one-hit wonders".
|
/// Bloom filter to avoid caching "one-hit wonders".
|
||||||
filter: BloomFilterU64,
|
bloom_filter: BloomFilterU64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for StringsInterner {
|
impl Default for StringsInterner {
|
||||||
@ -56,10 +53,8 @@ impl StringsInterner {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
capacity: MAX_INTERNED_STRINGS,
|
cache: StraightHashMap::new(),
|
||||||
max_string_len: MAX_STRING_LEN,
|
bloom_filter: BloomFilterU64::new(),
|
||||||
cache: StraightHashMap::default(),
|
|
||||||
filter: BloomFilterU64::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +82,14 @@ impl StringsInterner {
|
|||||||
let hash = hasher.finish();
|
let hash = hasher.finish();
|
||||||
|
|
||||||
// Cache long strings only on the second try to avoid caching "one-hit wonders".
|
// Cache long strings only on the second try to avoid caching "one-hit wonders".
|
||||||
if key.len() > MAX_STRING_LEN && self.filter.is_absent_and_set(hash) {
|
if key.len() > MAX_STRING_LEN && self.bloom_filter.is_absent_and_set(hash) {
|
||||||
return mapper(text);
|
return mapper(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.cache.is_empty() {
|
||||||
|
self.cache.reserve(MAX_INTERNED_STRINGS);
|
||||||
|
}
|
||||||
|
|
||||||
let result = match self.cache.entry(hash) {
|
let result = match self.cache.entry(hash) {
|
||||||
Entry::Occupied(e) => return e.get().clone(),
|
Entry::Occupied(e) => return e.get().clone(),
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
@ -110,26 +109,22 @@ impl StringsInterner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// If the interner is over capacity, remove the longest entry that has the lowest count
|
/// If the interner is over capacity, remove the longest entry that has the lowest count
|
||||||
fn throttle_cache(&mut self, hash: u64) {
|
#[inline]
|
||||||
if self.cache.len() <= self.capacity {
|
fn throttle_cache(&mut self, skip_hash: u64) {
|
||||||
|
if self.cache.len() <= MAX_INTERNED_STRINGS {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave some buffer to grow when shrinking the cache.
|
// Leave some buffer to grow when shrinking the cache.
|
||||||
// We leave at least two entries, one for the empty string, and one for the string
|
// We leave at least two entries, one for the empty string, and one for the string
|
||||||
// that has just been inserted.
|
// that has just been inserted.
|
||||||
let max = if self.capacity < 5 {
|
while self.cache.len() > MAX_INTERNED_STRINGS - 3 {
|
||||||
2
|
|
||||||
} else {
|
|
||||||
self.capacity - 3
|
|
||||||
};
|
|
||||||
|
|
||||||
while self.cache.len() > max {
|
|
||||||
let (_, _, n) = self
|
let (_, _, n) = self
|
||||||
.cache
|
.cache
|
||||||
.iter()
|
.iter()
|
||||||
.fold((0, usize::MAX, 0), |(x, c, n), (&k, v)| {
|
.fold((0, usize::MAX, 0), |(x, c, n), (&k, v)| {
|
||||||
if k != hash && (v.strong_count() < c || (v.strong_count() == c && v.len() > x))
|
if k != skip_hash
|
||||||
|
&& (v.strong_count() < c || (v.strong_count() == c && v.len() > x))
|
||||||
{
|
{
|
||||||
(v.len(), v.strong_count(), k)
|
(v.len(), v.strong_count(), k)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user