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; |         return ret; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn from_file(filename: &PathBuf) -> Self { |     pub fn from_file(filename: &PathBuf) -> (PathBuf, Self) { | ||||||
|         let t_load = Instant::now(); |         let t_load = Instant::now(); | ||||||
|         let mut reader = BufReader::new(File::open(&filename).unwrap()); |         let mut reader = BufReader::new(File::open(&filename).unwrap()); | ||||||
|         println!("Loading {}", filename.to_str().unwrap()); |         println!("Loading {}", filename.to_str().unwrap()); | ||||||
|  | @ -288,9 +288,16 @@ impl Router { | ||||||
|         if hash_file(&path) != file_hash { |         if hash_file(&path) != file_hash { | ||||||
|             panic!("File hash mismatch!") |             panic!("File hash mismatch!") | ||||||
|         } |         } | ||||||
|         let mut rtr = Self::new(&path, range, primary); |         return ( | ||||||
|         rtr.route_tree = Some(route_tree); |             path, | ||||||
|         return rtr; |             Self { | ||||||
|  |                 tree: RTree::default(), | ||||||
|  |                 scoopable: FnvHashSet::default(), | ||||||
|  |                 route_tree: Some(route_tree), | ||||||
|  |                 range, | ||||||
|  |                 primary_only: primary, | ||||||
|  |             }, | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn closest(&self, point: &[f32; 3]) -> &System { |     fn closest(&self, point: &[f32; 3]) -> &System { | ||||||
|  | @ -636,13 +643,91 @@ impl Router { | ||||||
|         self.route_tree = Some(prev); |         self.route_tree = Some(prev); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn route_to(&mut self, dst: &str) -> Vec<System> { |     fn get_systems_by_ids(path: &PathBuf, ids: &Vec<u32>) -> FnvHashMap<u32, System> { | ||||||
|         let mut id_map: FnvHashMap<u32, &System> = FnvHashMap::default(); |         let mut ret = FnvHashMap::default(); | ||||||
|         let mut id_set: FnvHashSet<u32> = FnvHashSet::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 prev = self.route_tree.as_ref().unwrap(); | ||||||
|         let mut dst = self.name_to_systems(dst); |         let dst = Self::get_system_by_name(&systems_path, dst); | ||||||
|         dst.sort_by_key(|&p| (p.mult * 10.0) as u8); |  | ||||||
|         let dst: System = dst.last().cloned().unwrap().clone(); |  | ||||||
|         if !prev.contains_key(&dst.id) { |         if !prev.contains_key(&dst.id) { | ||||||
|             eprintln!("System-ID {} not found", dst.id); |             eprintln!("System-ID {} not found", dst.id); | ||||||
|             std::process::exit(1); |             std::process::exit(1); | ||||||
|  | @ -652,7 +737,6 @@ impl Router { | ||||||
|         let mut curr_sys: u32 = dst.id; |         let mut curr_sys: u32 = dst.id; | ||||||
|         loop { |         loop { | ||||||
|             v_ids.push(curr_sys); |             v_ids.push(curr_sys); | ||||||
|             id_set.insert(curr_sys); |  | ||||||
|             match prev.get(&curr_sys) { |             match prev.get(&curr_sys) { | ||||||
|                 Some(sys_id) => curr_sys = *sys_id, |                 Some(sys_id) => curr_sys = *sys_id, | ||||||
|                 None => { |                 None => { | ||||||
|  | @ -661,13 +745,9 @@ impl Router { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         v_ids.reverse(); |         v_ids.reverse(); | ||||||
|         for sys in &self.tree { |         let id_map = Self::get_systems_by_ids(&systems_path, &v_ids); | ||||||
|             if id_set.contains(&sys.id) { |  | ||||||
|                 id_map.insert(sys.id, &sys); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         for sys_id in 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()) |             v.push(sys.clone()) | ||||||
|         } |         } | ||||||
|         return v; |         return v; | ||||||
|  | @ -769,9 +849,11 @@ fn main() { | ||||||
|         } |         } | ||||||
|         std::process::exit(1); |         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() { |     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 { |     } else { | ||||||
|         Router::new(&path, opts.range.unwrap(), opts.primary) |         Router::new(&path, opts.range.unwrap(), opts.primary) | ||||||
|     }; |     }; | ||||||
|  | @ -801,7 +883,7 @@ fn main() { | ||||||
|     } |     } | ||||||
|     let t_route = Instant::now(); |     let t_route = Instant::now(); | ||||||
|     let route = if router.route_tree.is_some() { |     let route = if router.route_tree.is_some() { | ||||||
|         router.route_to(opts.systems.first().unwrap()) |         router.route_to(opts.systems.first().unwrap(), &path) | ||||||
|     } else { |     } else { | ||||||
|         if opts.permute || opts.full_permute { |         if opts.permute || opts.full_permute { | ||||||
|             router.best_name_multiroute( |             router.best_name_multiroute( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue