diff --git a/.travis.yml b/.travis.yml index 0a110a9452..db5dd3dd8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: rust rust: - - 1.3.0 + - 1.6.0 - stable - beta - nightly diff --git a/Cargo.toml b/Cargo.toml index 2160b44447..933b29a524 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ aho-corasick = "0.5.1" # For skipping along search text quickly when a leading byte is known. memchr = "0.1.9" # For managing regex caches quickly across multiple threads. -mempool = "0.3.0" +thread_local = "0.2.0" # For parsing regular expressions. regex-syntax = { path = "regex-syntax", version = "0.3.1" } # For compiling UTF-8 decoding into automata. diff --git a/src/exec.rs b/src/exec.rs index 51c2edf740..018bb1a7db 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -12,7 +12,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::sync::Arc; -use mempool::Pool; +use thread_local::CachedThreadLocal; use syntax::{Expr, ExprBuilder, Literals}; use backtrack; @@ -33,12 +33,11 @@ use set; /// In particular, this manages the various compiled forms of a single regular /// expression and the choice of which matching engine to use to execute a /// regular expression. -#[derive(Debug)] pub struct Exec { /// All read only state. ro: Arc, /// Caches for the various matching engines. - cache: Pool, + cache: CachedThreadLocal, } /// ExecNoSync is like Exec, except it embeds a reference to a cache. This @@ -204,8 +203,7 @@ impl ExecBuilder { suffixes: LiteralSearcher::empty(), match_type: MatchType::Nothing, }); - let ro_ = ro.clone(); - return Ok(Exec { ro: ro, cache: create_pool(ro_) }); + return Ok(Exec { ro: ro, cache: CachedThreadLocal::new() }); } let parsed = try!(Parsed::parse(&self.res, self.only_utf8)); let mut nfa = try!( @@ -245,8 +243,7 @@ impl ExecBuilder { // println!("MATCH TYPE for '{:?}': {:?}", ro.res, ro.match_type); let ro = Arc::new(ro); - let ro_ = ro.clone(); - Ok(Exec { ro: ro, cache: create_pool(ro_) }) + Ok(Exec { ro: ro, cache: CachedThreadLocal::new() }) } } @@ -703,9 +700,10 @@ impl Exec { /// Get a searcher that isn't Sync. #[inline(always)] // reduces constant overhead pub fn searcher(&self) -> ExecNoSync { + let create = || Box::new(RefCell::new(ProgramCacheInner::new(&self.ro))); ExecNoSync { ro: &self.ro, // a clone is too expensive here! (and not needed) - cache: self.cache.get(), + cache: self.cache.get_or(create), } } @@ -759,7 +757,7 @@ impl Clone for Exec { fn clone(&self) -> Exec { Exec { ro: self.ro.clone(), - cache: create_pool(self.ro.clone()), + cache: CachedThreadLocal::new(), } } } @@ -863,11 +861,6 @@ pub struct ProgramCacheInner { pub dfa_reverse: dfa::Cache, } -/// Creates a fresh pool. -fn create_pool(ro: Arc) -> Pool { - Pool::new(Box::new(move || RefCell::new(ProgramCacheInner::new(&ro)))) -} - impl ProgramCacheInner { fn new(ro: &ExecReadOnly) -> Self { ProgramCacheInner { diff --git a/src/lib.rs b/src/lib.rs index dfc37451f6..61030ebe4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -505,7 +505,7 @@ extern crate aho_corasick; extern crate memchr; -extern crate mempool; +extern crate thread_local; #[cfg(test)] extern crate quickcheck; extern crate regex_syntax as syntax; extern crate utf8_ranges;