diff --git a/src/database/db_core.rs b/src/database/db_core.rs index a8a2a68..a7235af 100644 --- a/src/database/db_core.rs +++ b/src/database/db_core.rs @@ -7,6 +7,13 @@ use super::DataBase; use super::ResultSet; use crate::SpaceObject; +pub struct CoreQueryParameters<'a> { + pub db: &'a DataBase, + pub output_space: Option<&'a str>, + pub threshold_volume: Option, + pub resolution: Option>, +} + #[derive(Clone, Debug, Deserialize, Serialize)] pub enum Properties { Feature(String), @@ -149,9 +156,9 @@ impl Core { list: &mut [SpaceObject], space: &Space, db: &DataBase, - output_space: Option<&str>, + output_space: &Option<&str>, ) -> Result<(), String> { - if let Some(unified_id) = output_space { + if let Some(unified_id) = *output_space { let unified = db.space(unified_id)?; // Rebase the point to the requested output space before decoding. @@ -177,12 +184,17 @@ impl Core { // Positions ARE DEFINED IN F64 VALUES IN THE SPACE. NOT ENCODED! pub fn get_by_positions( &self, - db: &DataBase, + parameters: &CoreQueryParameters, positions: &[Position], from: &str, - output_space: Option<&str>, - threshold_volume: f64, ) -> ResultSet { + let CoreQueryParameters { + db, + output_space, + threshold_volume, + resolution, + } = parameters; + let mut results = vec![]; let count = positions.len(); let from = db.space(from)?; @@ -196,7 +208,7 @@ impl Core { p.push(to.encode(&position)?); } - let r = s.get_by_positions(&p, threshold_volume)?; + let r = s.get_by_positions(&p, threshold_volume, resolution)?; let mut r = self.to_space_object(s.name(), r); Self::decode_positions(&mut r, to, db, output_space)?; @@ -215,12 +227,17 @@ impl Core { // SHAPE IS DEFINED IN F64 VALUES IN THE SPACE. NOT ENCODED! pub fn get_by_shape( &self, - db: &DataBase, + parameters: &CoreQueryParameters, shape: &Shape, space_id: &str, - output_space: Option<&str>, - threshold_volume: f64, ) -> ResultSet { + let CoreQueryParameters { + db, + output_space, + threshold_volume, + resolution, + } = parameters; + let mut results = vec![]; let shape_space = db.space(space_id)?; @@ -232,7 +249,7 @@ impl Core { // let current_shape = shape.encode(current_space)?; // println!("current shape Encoded: {:?}", current_shape); - let r = s.get_by_shape(¤t_shape, threshold_volume)?; + let r = s.get_by_shape(¤t_shape, threshold_volume, resolution)?; let mut r = self.to_space_object(s.name(), r); Self::decode_positions(&mut r, current_space, db, output_space)?; @@ -244,16 +261,17 @@ impl Core { } // Search by Id, a.k.a values - pub fn get_by_id( - &self, - db: &DataBase, - id: S, - output_space: Option<&str>, - threshold_volume: f64, - ) -> ResultSet + pub fn get_by_id(&self, parameters: &CoreQueryParameters, id: S) -> ResultSet where S: Into, { + let CoreQueryParameters { + db, + output_space, + threshold_volume, + resolution, + } = parameters; + let id: String = id.into(); let mut results = vec![]; @@ -267,7 +285,7 @@ impl Core { for s in &self.space_db { let current_space = db.space(s.name())?; - let r = s.get_by_id(offset, threshold_volume)?; + let r = s.get_by_id(offset, threshold_volume, resolution)?; let mut r = self.to_space_object(s.name(), r); Self::decode_positions(&mut r, current_space, db, output_space)?; @@ -281,16 +299,17 @@ impl Core { // Search by Label, a.k.a within a volume defined by the positions of an Id. // FIXME: NEED TO KEEP TRACK OF SPACE IDS AND DO CONVERSIONS - pub fn get_by_label( - &self, - db: &DataBase, - id: S, - output_space: Option<&str>, - threshold_volume: f64, - ) -> ResultSet + pub fn get_by_label(&self, parameters: &CoreQueryParameters, id: S) -> ResultSet where S: Into, { + let CoreQueryParameters { + db, + output_space, + threshold_volume, + resolution, + } = parameters; + let id: String = id.into(); let mut results = vec![]; @@ -304,10 +323,12 @@ impl Core { let search_volume = self .space_db .iter() - .filter_map(|s| match s.get_by_id(offset, threshold_volume) { - Ok(v) => Some(v), - Err(_) => None, - }) + .filter_map( + |s| match s.get_by_id(offset, threshold_volume, resolution) { + Ok(v) => Some(v), + Err(_) => None, + }, + ) .flat_map(|v| v) .map(|o| o.position().clone()) .collect::>(); @@ -339,7 +360,7 @@ impl Core { for s in &self.space_db { let to = db.space(s.name())?; - let r = s.get_by_positions(&search_volume, threshold_volume)?; + let r = s.get_by_positions(&search_volume, threshold_volume, resolution)?; let mut r = self.to_space_object(s.name(), r); Self::decode_positions(&mut r, to, db, output_space)?; diff --git a/src/database/mod.rs b/src/database/mod.rs index e1bb496..908af32 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -12,6 +12,7 @@ use ironsea_table_vector::VectorTable; use memmap::Mmap; pub use db_core::Core; +pub use db_core::CoreQueryParameters; pub use db_core::Properties; use space::Position; use space::Space; diff --git a/src/database/space_db.rs b/src/database/space_db.rs index b192e65..bba70c3 100644 --- a/src/database/space_db.rs +++ b/src/database/space_db.rs @@ -85,7 +85,7 @@ impl SpaceDB { // Returns the index to be used by default for the given volume. // The index chosen by default will be the one with the smallest volume // threshold which is greater or equal to the query volume. - pub fn default_resolution(&self, volume: f64) -> usize { + fn default_resolution(&self, volume: f64) -> usize { for i in 0..self.resolutions.len() { if volume <= self.resolutions[i].threshold() { return i; @@ -94,6 +94,26 @@ impl SpaceDB { self.resolutions.len() } + fn find_resolution(&self, _scales: &[u64]) -> usize { + // FIXME: Implement stuff here! + self.lowest_resolution() + } + + pub fn get_resolution( + &self, + threshold_volume: &Option, + resolution: &Option>, + ) -> usize { + if let Some(threshold_volume) = threshold_volume { + self.default_resolution(*threshold_volume) + } else { + match resolution { + None => self.lowest_resolution(), + Some(v) => self.find_resolution(v), + } + } + } + // Convert the value back to caller's references fn decode(&self, mut objects: Vec) -> Vec { for o in &mut objects { @@ -107,13 +127,14 @@ impl SpaceDB { pub fn get_by_id( &self, id: usize, - threshold_volume: f64, + threshold_volume: &Option, + resolution: &Option>, ) -> Result, String> { // Is that ID referenced in the current space? if let Ok(offset) = self.values.binary_search(&id.into()) { - let resolution = self.default_resolution(threshold_volume); + let index = self.get_resolution(threshold_volume, resolution); - let mut results = self.resolutions[resolution] + let mut results = self.resolutions[index] .find_by_value(&SpaceFields::new(self.name().into(), offset.into())); // Convert the Value back to caller's references @@ -132,13 +153,14 @@ impl SpaceDB { pub fn get_by_positions( &self, positions: &[Position], - threshold_volume: f64, + threshold_volume: &Option, + resolution: &Option>, ) -> Result, String> { - let resolution = self.default_resolution(threshold_volume); + let index = self.get_resolution(threshold_volume, resolution); let results = positions .iter() - .flat_map(|position| self.resolutions[resolution].find(position)) + .flat_map(|position| self.resolutions[index].find(position)) .collect::>(); Ok(self.decode(results)) @@ -151,9 +173,11 @@ impl SpaceDB { pub fn get_by_shape( &self, shape: &Shape, - threshold_volume: f64, + threshold_volume: &Option, + resolution: &Option>, ) -> Result, String> { - let resolution = self.default_resolution(threshold_volume); - Ok(self.decode(self.resolutions[resolution].find_by_shape(&shape)?)) + let index = self.get_resolution(threshold_volume, resolution); + + Ok(self.decode(self.resolutions[index].find_by_shape(&shape)?)) } } diff --git a/src/main.rs b/src/main.rs index 3a55ce5..67be888 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,9 @@ #[macro_use] extern crate measure_time; -#[macro_use] -extern crate serde_derive; - -use mercator_db::json::model; use mercator_db::json::storage; use mercator_db::space::Shape; +use mercator_db::CoreQueryParameters; use mercator_db::DataBase; fn main() { @@ -39,16 +36,33 @@ fn main() { let core = db.core("10k").unwrap(); let space = db.space("std").unwrap(); let id = "oid0.5793259558369925"; - - let r = core.get_by_id(&db, id, None, std::f64::MAX).unwrap(); + let c = CoreQueryParameters { + db: &db, + output_space: None, + threshold_volume: Some(std::f64::MAX), + resolution: None, + }; + let r = core.get_by_id(&c, id).unwrap(); println!("get_by_id {}: {}", id, r.len()); println!("{}: {:?}\n", id, r[0]); - let r = core.get_by_id(&db, id, None, 0.0).unwrap(); + let c = CoreQueryParameters { + db: &db, + output_space: None, + threshold_volume: Some(0.0), + resolution: None, + }; + let r = core.get_by_id(&c, id).unwrap(); println!("get_by_id {}: {}", id, r.len()); println!("{}: {:?}\n", id, r[0]); - let r = core.get_by_label(&db, id, None, std::f64::MAX).unwrap(); + let c = CoreQueryParameters { + db: &db, + output_space: None, + threshold_volume: Some(std::f64::MAX), + resolution: None, + }; + let r = core.get_by_label(&c, id).unwrap(); println!("get_by_label {}: {}", id, r.len()); if !r.is_empty() { println!("{}: {:?}\n", id, r[0]); @@ -59,7 +73,13 @@ fn main() { let shape = Shape::BoundingBox(lower, higher); - let r = core.get_by_shape(&db, &shape, "std", None, 0.0).unwrap(); + let c = CoreQueryParameters { + db: &db, + output_space: None, + threshold_volume: Some(0.0), + resolution: None, + }; + let r = core.get_by_shape(&c, &shape, "std").unwrap(); println!("get_by_shape {:?}: {}", shape, r.len()); println!("{:?}: {:?}\n", shape, r[0]);