From a6865c6cbdaf0ec70eccc823012027828cccc2aa Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Wed, 30 Oct 2019 21:33:37 +0100 Subject: [PATCH] Update to new Index API, reduce allocations --- src/rest_api/actions.rs | 2 +- src/rest_api/spaces.rs | 6 ++--- src/rest_api/spatial_object.rs | 16 +++++++++++- src/rest_api/spatial_objects.rs | 44 ++++++++++++++++++++++----------- src/shared_state.rs | 26 +++++++++---------- 5 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/rest_api/actions.rs b/src/rest_api/actions.rs index 2c1f666..c58b22b 100644 --- a/src/rest_api/actions.rs +++ b/src/rest_api/actions.rs @@ -62,7 +62,7 @@ fn query((parameters, state): (Json, Data>)) -> Handl parameters.resolution(), ) { Err(_) => vec![], // FIXME: Return errors here instead!! - Ok(objects) => to_spatial_objects(context.db(), objects), + Ok(objects) => to_spatial_objects(objects), } }) .collect::>(), diff --git a/src/rest_api/spaces.rs b/src/rest_api/spaces.rs index 738bfc6..e568cc4 100644 --- a/src/rest_api/spaces.rs +++ b/src/rest_api/spaces.rs @@ -53,11 +53,11 @@ fn post((parameters, state): (Json, Data>)) -> Hand parameters.resolution(), ) { Err(e) => return error_422(e), - Ok(objects) => { + Ok(v) => { // We have a list of SpaceObjects, so extract // the space Ids - for o in objects { - results.insert(o.space_id); + for (space_id, _) in v { + results.insert(space_id); } } } diff --git a/src/rest_api/spatial_object.rs b/src/rest_api/spatial_object.rs index fc9c0f5..298bdf5 100644 --- a/src/rest_api/spatial_object.rs +++ b/src/rest_api/spatial_object.rs @@ -4,6 +4,7 @@ use actix_web::web; use actix_web::web::Data; use actix_web::web::Path; use mercator_db::CoreQueryParameters; +use mercator_db::Properties; use crate::model::to_spatial_objects; use crate::shared_state::SharedState; @@ -39,7 +40,20 @@ fn get((path, state): (Path<(String, String)>, Data>)) -> Ha match db.core(&core) { Ok(core) => match core.get_by_id(¶meters, &id) { Ok(objects) => { - let results = to_spatial_objects(db, objects); + let value = Properties::Feature(id); + let tmp = objects + .into_iter() + .map(|(space, positions)| { + let shapes = positions + .into_iter() + .map(|position| (position, &value)) + .collect(); + (space, shapes) + }) + .collect(); + + let results = to_spatial_objects(tmp); + if results.is_empty() { error_404() } else { diff --git a/src/rest_api/spatial_objects.rs b/src/rest_api/spatial_objects.rs index 771ddff..c1fe4c2 100644 --- a/src/rest_api/spatial_objects.rs +++ b/src/rest_api/spatial_objects.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::collections::HashSet; use std::sync::RwLock; @@ -31,13 +32,13 @@ fn post( Err(e) => e, Ok(space) => match parameters.filters() { None => { - let mut results = HashSet::new(); + let mut results = HashMap::new(); for property in core.keys().iter() { - results.insert(property.id()); + results.insert(property.id(), property); } if parameters.ids_only() { - ok_200(&results.drain().collect::>()) + ok_200(&results.drain().map(|(k, _)| k).collect::>()) } else { let core_parameters = CoreQueryParameters { db, @@ -47,14 +48,27 @@ fn post( resolution: parameters.resolution(), }; - let objects = results - .drain() - .flat_map(|id| match core.get_by_id(&core_parameters, id) { - Err(_) => vec![], // FIXME: Return error ? - Ok(r) => r, - }) - .collect::>(); - let objects = to_spatial_objects(db, objects); + let mut objects = vec![]; + for (id, properties) in results.drain() { + match core.get_by_id(&core_parameters, id) { + Err(_) => (), // FIXME: Return error ? + Ok(r) => { + let mut tmp = r + .into_iter() + .map(|(space, positions)| { + let shapes = positions + .into_iter() + .map(|position| (position, properties)) + .collect(); + (space, shapes) + }) + .collect(); + objects.append(&mut tmp); + } + } + } + + let objects = to_spatial_objects(objects); ok_200(&objects) } @@ -72,13 +86,15 @@ fn post( Ok(objects) => { if parameters.ids_only() { let mut uniques = HashSet::new(); - for o in objects.iter() { - uniques.insert(o.value.id()); + for (_, v) in objects { + for (_, properties) in v { + uniques.insert(properties.id()); + } } ok_200(&uniques.drain().collect::>()) } else { - let objects = to_spatial_objects(db, objects); + let objects = to_spatial_objects(objects); ok_200(&objects) } diff --git a/src/shared_state.rs b/src/shared_state.rs index 1f96ae2..4d0bc2c 100644 --- a/src/shared_state.rs +++ b/src/shared_state.rs @@ -32,15 +32,15 @@ impl SharedState { &self.query_parser } - pub fn filter( - &self, - filter: &str, - core: &str, - output_space: &Option, + pub fn filter<'q>( + &'q self, + filter: &'q str, + core: &'q str, + output_space: &'q Option, volume: Option, - view_port: &Option<(Vec, Vec)>, - resolution: &Option>, - ) -> mercator_db::ResultSet { + view_port: &'q Option<(Vec, Vec)>, + resolution: &'q Option>, + ) -> mercator_db::ResultSet<'q> { let parser = self.filter_parser(); let parse; let parameters = CoreQueryParameters { @@ -92,14 +92,14 @@ impl SharedState { } } - pub fn query( - &self, + pub fn query<'q>( + &'q self, query: &str, core: &str, volume: Option, - view_port: &Option<(Vec, Vec)>, - resolution: &Option>, - ) -> mercator_db::ResultSet { + view_port: &'q Option<(Vec, Vec)>, + resolution: &'q Option>, + ) -> mercator_db::ResultSet<'q> { let parser = self.query_parser(); let parse; let parameters = CoreQueryParameters {