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…
Reference in a new issue