From cecc7ad5b20e693cb8d962187bd83b9ac234de97 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 12 Sep 2018 22:11:26 +0300 Subject: be generic over data --- crates/salsa/src/lib.rs | 91 +++++++++++++++++++++------------------ crates/salsa/tests/integration.rs | 25 +++++------ 2 files changed, 61 insertions(+), 55 deletions(-) (limited to 'crates') diff --git a/crates/salsa/src/lib.rs b/crates/salsa/src/lib.rs index 69c7b35fa..a54f2a06f 100644 --- a/crates/salsa/src/lib.rs +++ b/crates/salsa/src/lib.rs @@ -3,53 +3,52 @@ extern crate parking_lot; use std::{ sync::Arc, - any::Any, collections::HashMap, cell::RefCell, }; use parking_lot::Mutex; -type GroundQueryFn = fn(&T, &(Any + Send + Sync + 'static)) -> (Box, OutputFingerprint); -type QueryFn = fn(&QueryCtx, &(Any + Send + Sync + 'static)) -> (Box, OutputFingerprint); +type GroundQueryFn = fn(&T, &D) -> (D, OutputFingerprint); +type QueryFn = fn(&QueryCtx, &D) -> (D, OutputFingerprint); #[derive(Debug)] -pub struct Db { - db: Arc>, - query_config: Arc>, +pub struct Db { + db: Arc>, + query_config: Arc>, } -pub struct QueryConfig { - ground_fn: HashMap>, - query_fn: HashMap>, +pub struct QueryConfig { + ground_fn: HashMap>, + query_fn: HashMap>, } -impl ::std::fmt::Debug for QueryConfig { +impl ::std::fmt::Debug for QueryConfig { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { ::std::fmt::Display::fmt("QueryConfig { ... }", f) } } #[derive(Debug)] -struct DbState { +struct DbState { ground_data: T, gen: Gen, - graph: Mutex)>>, + graph: Mutex>)>>, } #[derive(Debug)] -struct QueryRecord { - params: Arc, - output: Arc, +struct QueryRecord { + params: D, + output: D, output_fingerprint: OutputFingerprint, deps: Vec<(QueryId, OutputFingerprint)>, } -impl DbState { +impl DbState { fn record( &self, query_id: QueryId, - params: Arc, - output: Arc, + params: D, + output: D, output_fingerprint: OutputFingerprint, deps: Vec<(QueryId, OutputFingerprint)>, ) { @@ -64,7 +63,7 @@ impl DbState { } } -impl QueryConfig { +impl QueryConfig { pub fn new() -> Self { QueryConfig { ground_fn: HashMap::new(), @@ -74,7 +73,7 @@ impl QueryConfig { pub fn with_ground_query( mut self, query_type: QueryTypeId, - query_fn: GroundQueryFn + query_fn: GroundQueryFn ) -> Self { let prev = self.ground_fn.insert(query_type, query_fn); assert!(prev.is_none()); @@ -83,7 +82,7 @@ impl QueryConfig { pub fn with_query( mut self, query_type: QueryTypeId, - query_fn: QueryFn, + query_fn: QueryFn, ) -> Self { let prev = self.query_fn.insert(query_type, query_fn); assert!(prev.is_none()); @@ -91,15 +90,18 @@ impl QueryConfig { } } -pub struct QueryCtx { - db: Arc>, - query_config: Arc>, +pub struct QueryCtx { + db: Arc>, + query_config: Arc>, stack: RefCell>>, executed: RefCell>, } -impl QueryCtx { - fn new(db: &Db) -> QueryCtx { +impl QueryCtx +where + D: Clone +{ + fn new(db: &Db) -> QueryCtx { QueryCtx { db: Arc::clone(&db.db), query_config: Arc::clone(&db.query_config), @@ -110,8 +112,8 @@ impl QueryCtx { pub fn get( &self, query_id: QueryId, - params: Arc, - ) -> Arc { + params: D, + ) -> D { let (res, output_fingerprint) = self.get_inner(query_id, params); self.record_dep(query_id, output_fingerprint); res @@ -120,8 +122,8 @@ impl QueryCtx { pub fn get_inner( &self, query_id: QueryId, - params: Arc, - ) -> (Arc, OutputFingerprint) { + params: D, + ) -> (D, OutputFingerprint) { let (gen, record) = { let guard = self.db.graph.lock(); match guard.get(&query_id).map(|it| it.clone()){ @@ -139,7 +141,7 @@ impl QueryCtx { return self.force(query_id, params); } for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() { - let dep_params: Arc = { + let dep_params: D = { let guard = self.db.graph.lock(); guard[&dep_query_id] .1 @@ -160,29 +162,29 @@ impl QueryCtx { fn force( &self, query_id: QueryId, - params: Arc, - ) -> (Arc, OutputFingerprint) { + params: D, + ) -> (D, OutputFingerprint) { self.executed.borrow_mut().push(query_id.0); self.stack.borrow_mut().push(Vec::new()); let (res, output_fingerprint) = if let Some(f) = self.ground_query_fn_by_type(query_id.0) { - f(&self.db.ground_data, &*params) + f(&self.db.ground_data, ¶ms) } else if let Some(f) = self.query_fn_by_type(query_id.0) { - f(self, &*params) + f(self, ¶ms) } else { panic!("unknown query type: {:?}", query_id.0); }; - let res: Arc = res.into(); + let res: D = res.into(); let deps = self.stack.borrow_mut().pop().unwrap(); self.db.record(query_id, params, res.clone(), output_fingerprint, deps); (res, output_fingerprint) } - fn ground_query_fn_by_type(&self, query_type: QueryTypeId) -> Option> { + fn ground_query_fn_by_type(&self, query_type: QueryTypeId) -> Option> { self.query_config.ground_fn.get(&query_type).map(|&it| it) } - fn query_fn_by_type(&self, query_type: QueryTypeId) -> Option> { + fn query_fn_by_type(&self, query_type: QueryTypeId) -> Option> { self.query_config.query_fn.get(&query_type).map(|&it| it) } fn record_dep( @@ -196,15 +198,18 @@ impl QueryCtx { } } -impl Db { - pub fn new(query_config: QueryConfig, ground_data: T) -> Db { +impl Db +where + D: Clone +{ + pub fn new(query_config: QueryConfig, ground_data: T) -> Db { Db { db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }), query_config: Arc::new(query_config), } } - pub fn with_ground_data(&self, ground_data: T) -> Db { + pub fn with_ground_data(&self, ground_data: T) -> Db { let gen = Gen(self.db.gen.0 + 1); let graph = self.db.graph.lock().clone(); let graph = Mutex::new(graph); @@ -216,8 +221,8 @@ impl Db { pub fn get( &self, query_id: QueryId, - params: Box, - ) -> (Arc, Vec) { + params: D, + ) -> (D, Vec) { let ctx = QueryCtx::new(self); let res = ctx.get(query_id, params.into()); let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new()); diff --git a/crates/salsa/tests/integration.rs b/crates/salsa/tests/integration.rs index 7241eca38..2872d3913 100644 --- a/crates/salsa/tests/integration.rs +++ b/crates/salsa/tests/integration.rs @@ -7,6 +7,7 @@ use std::{ }; type State = HashMap; +type Data = Arc; const GET_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(1); const GET_FILES: salsa::QueryTypeId = salsa::QueryTypeId(2); const FILE_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(3); @@ -14,9 +15,9 @@ const TOTAL_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(4); fn mk_ground_query( state: &State, - params: &(Any + Send + Sync + 'static), + params: &Data, f: fn(&State, &T) -> R, -) -> (Box, salsa::OutputFingerprint) +) -> (Data, salsa::OutputFingerprint) where T: 'static, R: Hash + Send + Sync + 'static, @@ -24,21 +25,21 @@ where let params = params.downcast_ref().unwrap(); let result = f(state, params); let fingerprint = o_print(&result); - (Box::new(result), fingerprint) + (Arc::new(result), fingerprint) } -fn get(db: &salsa::Db, query_type: salsa::QueryTypeId, param: T) -> (Arc, Vec) +fn get(db: &salsa::Db, query_type: salsa::QueryTypeId, param: T) -> (Arc, Vec) where T: Hash + Send + Sync + 'static, R: Send + Sync + 'static, { let i_print = i_print(¶m); - let param = Box::new(param); + let param = Arc::new(param); let (res, trace) = db.get(salsa::QueryId(query_type, i_print), param); (res.downcast().unwrap(), trace) } -struct QueryCtx<'a>(&'a salsa::QueryCtx); +struct QueryCtx<'a>(&'a salsa::QueryCtx); impl<'a> QueryCtx<'a> { fn get_text(&self, id: u32) -> Arc { @@ -60,10 +61,10 @@ impl<'a> QueryCtx<'a> { } fn mk_query( - query_ctx: &salsa::QueryCtx, - params: &(Any + Send + Sync + 'static), + query_ctx: &salsa::QueryCtx, + params: &Data, f: fn(QueryCtx, &T) -> R, -) -> (Box, salsa::OutputFingerprint) +) -> (Data, salsa::OutputFingerprint) where T: 'static, R: Hash + Send + Sync + 'static, @@ -72,11 +73,11 @@ where let query_ctx = QueryCtx(query_ctx); let result = f(query_ctx, params); let fingerprint = o_print(&result); - (Box::new(result), fingerprint) + (Arc::new(result), fingerprint) } -fn mk_queries() -> salsa::QueryConfig { - salsa::QueryConfig::::new() +fn mk_queries() -> salsa::QueryConfig { + salsa::QueryConfig::::new() .with_ground_query(GET_TEXT, |state, id| { mk_ground_query::(state, id, |state, id| state[id].clone()) }) -- cgit v1.2.3