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