Update main.rs
Accelerate search for multiple systems by id/name by doing a single pass and returning a map
This commit is contained in:
		
							parent
							
								
									273e5c74c3
								
							
						
					
					
						commit
						bac5907f15
					
				
					 1 changed files with 102 additions and 20 deletions
				
			
		
							
								
								
									
										122
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										122
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -272,7 +272,7 @@ impl Router { | |||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_file(filename: &PathBuf) -> Self { | ||||
|     pub fn from_file(filename: &PathBuf) -> (PathBuf, Self) { | ||||
|         let t_load = Instant::now(); | ||||
|         let mut reader = BufReader::new(File::open(&filename).unwrap()); | ||||
|         println!("Loading {}", filename.to_str().unwrap()); | ||||
|  | @ -288,9 +288,16 @@ impl Router { | |||
|         if hash_file(&path) != file_hash { | ||||
|             panic!("File hash mismatch!") | ||||
|         } | ||||
|         let mut rtr = Self::new(&path, range, primary); | ||||
|         rtr.route_tree = Some(route_tree); | ||||
|         return rtr; | ||||
|         return ( | ||||
|             path, | ||||
|             Self { | ||||
|                 tree: RTree::default(), | ||||
|                 scoopable: FnvHashSet::default(), | ||||
|                 route_tree: Some(route_tree), | ||||
|                 range, | ||||
|                 primary_only: primary, | ||||
|             }, | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     fn closest(&self, point: &[f32; 3]) -> &System { | ||||
|  | @ -636,13 +643,91 @@ impl Router { | |||
|         self.route_tree = Some(prev); | ||||
|     } | ||||
| 
 | ||||
|     pub fn route_to(&mut self, dst: &str) -> Vec<System> { | ||||
|         let mut id_map: FnvHashMap<u32, &System> = FnvHashMap::default(); | ||||
|         let mut id_set: FnvHashSet<u32> = FnvHashSet::default(); | ||||
|     fn get_systems_by_ids(path: &PathBuf, ids: &Vec<u32>) -> FnvHashMap<u32, System> { | ||||
|         let mut ret = FnvHashMap::default(); | ||||
|         let mut reader = csv::ReaderBuilder::new() | ||||
|             .from_path(path) | ||||
|             .unwrap_or_else(|e| { | ||||
|                 println!("Error opening {}: {}", path.to_str().unwrap(), e); | ||||
|                 std::process::exit(1); | ||||
|             }); | ||||
|         reader | ||||
|             .deserialize::<SystemSerde>() | ||||
|             .map(|res| res.unwrap()) | ||||
|             .filter(|sys| ids.contains(&sys.id)) | ||||
|             .map(|sys| { | ||||
|                 ret.insert( | ||||
|                     sys.id, | ||||
|                     System { | ||||
|                         id: sys.id, | ||||
|                         star_type: sys.star_type, | ||||
|                         name: sys.name, | ||||
|                         mult: sys.mult, | ||||
|                         distance: sys.distance, | ||||
|                         pos: [sys.x, sys.y, sys.z], | ||||
|                     }, | ||||
|                 ); | ||||
|             }) | ||||
|             .last() | ||||
|             .expect(&format!("No systems matching {:?} found!", ids)); | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     fn get_systems_by_names(path: &PathBuf, names: &Vec<String>) -> FnvHashMap<String, System> { | ||||
|         let mut ret = FnvHashMap::default(); | ||||
|         let mut reader = csv::ReaderBuilder::new() | ||||
|             .from_path(path) | ||||
|             .unwrap_or_else(|e| { | ||||
|                 println!("Error opening {}: {}", path.to_str().unwrap(), e); | ||||
|                 std::process::exit(1); | ||||
|             }); | ||||
|         reader | ||||
|             .deserialize::<SystemSerde>() | ||||
|             .map(|res| res.unwrap()) | ||||
|             .filter(|sys| names.contains(&sys.name)) | ||||
|             .map(|sys| { | ||||
|                 ret.insert( | ||||
|                     sys.name.clone(), | ||||
|                     System { | ||||
|                         id: sys.id, | ||||
|                         star_type: sys.star_type, | ||||
|                         name: sys.name, | ||||
|                         mult: sys.mult, | ||||
|                         distance: sys.distance, | ||||
|                         pos: [sys.x, sys.y, sys.z], | ||||
|                     }, | ||||
|                 ); | ||||
|             }) | ||||
|             .last() | ||||
|             .expect(&format!("No systems matching {:?} found!", names)); | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     fn get_system_by_name(path: &PathBuf, name: &str) -> System { | ||||
|         let mut reader = csv::ReaderBuilder::new() | ||||
|             .from_path(path) | ||||
|             .unwrap_or_else(|e| { | ||||
|                 println!("Error opening {}: {}", path.to_str().unwrap(), e); | ||||
|                 std::process::exit(1); | ||||
|             }); | ||||
|         let sys = reader | ||||
|             .deserialize::<SystemSerde>() | ||||
|             .map(|res| res.unwrap()) | ||||
|             .find(|sys| sys.name == name) | ||||
|             .expect(&format!("System '{}' not found!", name)); | ||||
|         return System { | ||||
|             id: sys.id, | ||||
|             star_type: sys.star_type, | ||||
|             name: sys.name, | ||||
|             mult: sys.mult, | ||||
|             distance: sys.distance, | ||||
|             pos: [sys.x, sys.y, sys.z], | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     pub fn route_to(&mut self, dst: &str, systems_path: &PathBuf) -> Vec<System> { | ||||
|         let prev = self.route_tree.as_ref().unwrap(); | ||||
|         let mut dst = self.name_to_systems(dst); | ||||
|         dst.sort_by_key(|&p| (p.mult * 10.0) as u8); | ||||
|         let dst: System = dst.last().cloned().unwrap().clone(); | ||||
|         let dst = Self::get_system_by_name(&systems_path, dst); | ||||
|         if !prev.contains_key(&dst.id) { | ||||
|             eprintln!("System-ID {} not found", dst.id); | ||||
|             std::process::exit(1); | ||||
|  | @ -652,7 +737,6 @@ impl Router { | |||
|         let mut curr_sys: u32 = dst.id; | ||||
|         loop { | ||||
|             v_ids.push(curr_sys); | ||||
|             id_set.insert(curr_sys); | ||||
|             match prev.get(&curr_sys) { | ||||
|                 Some(sys_id) => curr_sys = *sys_id, | ||||
|                 None => { | ||||
|  | @ -661,13 +745,9 @@ impl Router { | |||
|             } | ||||
|         } | ||||
|         v_ids.reverse(); | ||||
|         for sys in &self.tree { | ||||
|             if id_set.contains(&sys.id) { | ||||
|                 id_map.insert(sys.id, &sys); | ||||
|             } | ||||
|         } | ||||
|         let id_map = Self::get_systems_by_ids(&systems_path, &v_ids); | ||||
|         for sys_id in v_ids { | ||||
|             let sys = *(id_map.get(&sys_id).unwrap()); | ||||
|             let sys = id_map.get(&sys_id).unwrap(); | ||||
|             v.push(sys.clone()) | ||||
|         } | ||||
|         return v; | ||||
|  | @ -769,9 +849,11 @@ fn main() { | |||
|         } | ||||
|         std::process::exit(1); | ||||
|     } | ||||
|     let path = opts.file_path; | ||||
|     let mut path = opts.file_path; | ||||
|     let mut router: Router = if opts.precomp_file.is_some() { | ||||
|         Router::from_file(&opts.precomp_file.unwrap()) | ||||
|         let ret = Router::from_file(&opts.precomp_file.clone().unwrap()); | ||||
|         path = ret.0; | ||||
|         ret.1 | ||||
|     } else { | ||||
|         Router::new(&path, opts.range.unwrap(), opts.primary) | ||||
|     }; | ||||
|  | @ -801,7 +883,7 @@ fn main() { | |||
|     } | ||||
|     let t_route = Instant::now(); | ||||
|     let route = if router.route_tree.is_some() { | ||||
|         router.route_to(opts.systems.first().unwrap()) | ||||
|         router.route_to(opts.systems.first().unwrap(), &path) | ||||
|     } else { | ||||
|         if opts.permute || opts.full_permute { | ||||
|             router.best_name_multiroute( | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue