diff --git a/10k.index b/10k.index index 0c1c837..06facd8 100644 Binary files a/10k.index and b/10k.index differ diff --git a/src/evaluators.rs b/src/evaluators.rs index 5bfdb25..3c74ae1 100644 --- a/src/evaluators.rs +++ b/src/evaluators.rs @@ -1,10 +1,13 @@ -use mercator_db::SpaceObject; +use mercator_db::space; +use mercator_db::Properties; use super::expressions::*; use super::symbols::*; -impl Evaluator for Predicate { - fn eval(&self, object: &SpaceObject) -> bool { +impl<'e> Evaluator<'e> for Predicate { + type Object = (&'e String, &'e space::Position, &'e Properties); + + fn eval(&self, object: Self::Object) -> bool { match self { Predicate::Not(predicate) => !predicate.eval(object), Predicate::And(lh, rh) => lh.eval(object) && rh.eval(object), diff --git a/src/executors.rs b/src/executors.rs index 8633292..7f3cc95 100644 --- a/src/executors.rs +++ b/src/executors.rs @@ -1,9 +1,9 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use mercator_db::space; use mercator_db::Core; use mercator_db::CoreQueryParameters; -use mercator_db::SpaceObject; +use mercator_db::Properties; use super::expressions::*; use super::symbols::*; @@ -24,23 +24,36 @@ impl From<&LiteralNumber> for space::Coordinate { } } -fn complement_helper( - core: &Core, - parameters: &CoreQueryParameters, +fn complement_helper<'c>( + core: &'c Core, + parameters: &CoreQueryParameters<'c>, space_id: &str, - inside: Vec, -) -> mercator_db::ResultSet { + inside: Vec<(&'c String, Vec<(space::Position, &'c Properties)>)>, +) -> mercator_db::ResultSet<'c> { let (low, high) = parameters.db.space(space_id)?.bounding_box(); match core.get_by_shape(parameters, &space::Shape::BoundingBox(low, high), space_id) { e @ Err(_) => e, - Ok(points) => Ok(points - .into_iter() - .filter(|o| !inside.contains(&o)) - .collect::>()), + Ok(points) => { + let hashmap = inside.into_iter().collect::>(); + + Ok(points + .into_iter() + .filter_map(|(space, v)| match hashmap.get(space) { + None => None, + Some(list) => { + Some((space, v.into_iter().filter(|t| !list.contains(t)).collect())) + } + }) + .collect::>()) + } } } -fn view_port(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> mercator_db::ResultSet { +fn view_port<'c>( + core_id: &str, + parameters: &CoreQueryParameters<'c>, + bag: &Bag, +) -> mercator_db::ResultSet<'c> { if let Some((low, high)) = parameters.view_port { let vp = Bag::Inside(Shape::HyperRectangle( bag.space().clone(), @@ -52,7 +65,11 @@ fn view_port(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> merc } } -fn distinct(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> mercator_db::ResultSet { +fn distinct<'c>( + core_id: &str, + parameters: &CoreQueryParameters<'c>, + bag: &Bag, +) -> mercator_db::ResultSet<'c> { match bag.execute(core_id, parameters) { e @ Err(_) => e, Ok(mut v) => { @@ -64,30 +81,42 @@ fn distinct(core_id: &str, parameters: &CoreQueryParameters, bag: &Bag) -> merca } } -fn filter( +fn filter<'c>( core_id: &str, - parameters: &CoreQueryParameters, + parameters: &CoreQueryParameters<'c>, predicate: &Option, bag: &Bag, -) -> mercator_db::ResultSet { +) -> mercator_db::ResultSet<'c> { match predicate { None => bag.execute(core_id, parameters), Some(predicate) => match bag.execute(core_id, parameters) { e @ Err(_) => e, Ok(results) => Ok(results .into_iter() - .filter(|o| predicate.eval(&o)) + .filter_map(|(space, positions)| { + let filtered = positions + .into_iter() + .filter(|(position, properties)| { + predicate.eval((space, position, properties)) + }) + .collect::>(); + if filtered.is_empty() { + None + } else { + Some((space, filtered)) + } + }) .collect::>()), }, } } -fn complement( +fn complement<'c>( core_id: &str, - parameters: &CoreQueryParameters, - core: &Core, + parameters: &CoreQueryParameters<'c>, + core: &'c Core, bag: &Bag, -) -> mercator_db::ResultSet { +) -> mercator_db::ResultSet<'c> { match bag.execute(core_id, parameters) { // FIXME: The complement of a set is computed within its definition space. e @ Err(_) => e, @@ -100,12 +129,12 @@ fn complement( } } -fn intersection( +fn intersection<'c>( core_id: &str, - parameters: &CoreQueryParameters, + parameters: &CoreQueryParameters<'c>, rh: &Bag, lh: &Bag, -) -> mercator_db::ResultSet { +) -> mercator_db::ResultSet<'c> { let l = lh.execute(core_id, parameters); if let Ok(l) = l { let r = rh.execute(core_id, parameters); @@ -134,12 +163,12 @@ fn intersection( } } -fn union( +fn union<'c>( core_id: &str, - parameters: &CoreQueryParameters, + parameters: &CoreQueryParameters<'c>, rh: &Bag, lh: &Bag, -) -> mercator_db::ResultSet { +) -> mercator_db::ResultSet<'c> { let l = lh.execute(core_id, parameters); if let Ok(mut l) = l { let r = rh.execute(core_id, parameters); @@ -159,7 +188,11 @@ fn union( } } -fn bag(core_id: &str, parameters: &CoreQueryParameters, bags: &[Bag]) -> mercator_db::ResultSet { +fn bag<'c>( + core_id: &str, + parameters: &CoreQueryParameters<'c>, + bags: &[Bag], +) -> mercator_db::ResultSet<'c> { let mut v = vec![]; for bag in bags { let b = bag.execute(core_id, parameters); @@ -176,7 +209,11 @@ fn bag(core_id: &str, parameters: &CoreQueryParameters, bags: &[Bag]) -> mercato Ok(v) } -fn inside(parameters: &CoreQueryParameters, core: &Core, shape: &Shape) -> mercator_db::ResultSet { +fn inside<'c>( + parameters: &CoreQueryParameters<'c>, + core: &'c Core, + shape: &Shape, +) -> mercator_db::ResultSet<'c> { let db = parameters.db; let param = match shape { Shape::Point(space_id, position) => { @@ -220,7 +257,11 @@ fn inside(parameters: &CoreQueryParameters, core: &Core, shape: &Shape) -> merca } } -fn outside(parameters: &CoreQueryParameters, core: &Core, shape: &Shape) -> mercator_db::ResultSet { +fn outside<'c>( + parameters: &CoreQueryParameters<'c>, + core: &'c Core, + shape: &Shape, +) -> mercator_db::ResultSet<'c> { match shape { Shape::Point(space_id, position) => { let position: Vec = position.into(); @@ -273,10 +314,14 @@ fn outside(parameters: &CoreQueryParameters, core: &Core, shape: &Shape) -> merc } } -impl Executor for Projection { - type ResultSet = mercator_db::ResultSet; +impl<'e> Executor<'e> for Projection { + type ResultSet = mercator_db::ResultSet<'e>; - fn execute(&self, core_id: &str, parameters: &CoreQueryParameters) -> Self::ResultSet { + fn execute<'f: 'e>( + &self, + core_id: &str, + parameters: &CoreQueryParameters<'f>, + ) -> Self::ResultSet { match self { Projection::Nifti(_, _, _bag) => Err("Proj-Nifti: not yet implemented".to_string()), Projection::JSON(_, _format, bag) => { @@ -287,10 +332,14 @@ impl Executor for Projection { } } -impl Executor for Bag { - type ResultSet = mercator_db::ResultSet; +impl<'e> Executor<'e> for Bag { + type ResultSet = mercator_db::ResultSet<'e>; - fn execute(&self, core_id: &str, parameters: &CoreQueryParameters) -> Self::ResultSet { + fn execute<'f: 'e>( + &self, + core_id: &str, + parameters: &CoreQueryParameters<'f>, + ) -> Self::ResultSet { let core = parameters.db.core(core_id)?; match self { diff --git a/src/expressions.rs b/src/expressions.rs index 22669c3..8f0d330 100644 --- a/src/expressions.rs +++ b/src/expressions.rs @@ -1,6 +1,5 @@ use mercator_db::CoreQueryParameters; use mercator_db::DataBase; -use mercator_db::SpaceObject; pub trait Validator { type ValidationResult; @@ -12,12 +11,18 @@ pub trait Predictor { fn predict(&self, db: &DataBase) -> Result; } -pub trait Executor { +pub trait Executor<'e> { type ResultSet; - fn execute(&self, core_id: &str, parameters: &CoreQueryParameters) -> Self::ResultSet; + fn execute<'f: 'e>( + &self, + core_id: &str, + parameters: &CoreQueryParameters<'f>, + ) -> Self::ResultSet; } -pub trait Evaluator { - fn eval(&self, object: &SpaceObject) -> bool; +pub trait Evaluator<'e> { + type Object; + + fn eval(&self, object: Self::Object) -> bool; } diff --git a/src/main.rs b/src/main.rs index b287394..539345b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ fn main() { output_space: None, threshold_volume: None, view_port: &None, - resolution: None, + resolution: &None, }; let parser = QueryParser::new(); let parser = FiltersParser::new(); diff --git a/src/symbols.rs b/src/symbols.rs index 24094c1..026f548 100644 --- a/src/symbols.rs +++ b/src/symbols.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use mercator_db::space; -use mercator_db::SpaceObject; +use mercator_db::Properties; pub use super::types::*; @@ -217,7 +217,10 @@ pub enum Position { } impl Position { - pub fn value(&self, object: &SpaceObject) -> LiteralPosition { + pub fn value<'e>( + &self, + object: (&'e String, &'e space::Position, &'e Properties), + ) -> LiteralPosition { match self { Position::Literal(literal) => literal.clone(), Position::Selector(selector) => selector.position(object), @@ -347,6 +350,12 @@ impl From<&Vec> for LiteralPosition { LiteralPosition(lv) } } +impl From<&space::Position> for LiteralPosition { + fn from(position: &space::Position) -> Self { + let lv: Vec = position.into(); + (&lv).into() + } +} impl PartialOrd for LiteralPosition { fn partial_cmp(&self, other: &LiteralPosition) -> Option { @@ -394,24 +403,25 @@ impl LiteralSelector { } // FIXME: THIS IS SOOO WRONG - pub fn position(&self, object: &SpaceObject) -> LiteralPosition { + pub fn position<'e>( + &self, + object: (&'e String, &'e space::Position, &'e Properties), + ) -> LiteralPosition { println!("LiteralSelector.position(): {:?}", self); - let v: Vec = object.position.clone().into(); - - LiteralPosition(v.into_iter().map(LiteralNumber::Float).collect::>()) + object.1.into() } // FIXME: THIS IS SOOO WRONG - pub fn str(&self, object: &SpaceObject) -> String { + pub fn str<'e>(&self, object: (&'e String, &'e space::Position, &'e Properties)) -> String { let LiteralSelector(v) = self; let last = v.last(); if let Some(Field(name, _)) = last { if name == "id" { - return object.value.id().into(); + return object.2.id().into(); } else if name == "type" { - return object.value.type_name().into(); + return object.2.type_name().into(); } else if name == "reference_space" { - return object.space_id.clone(); + return object.0.clone(); } }