don't use a bimap for NodeMap. less dependencies, marginal speed boost

This commit is contained in:
Dustin Carlino 2019-06-27 10:00:20 -07:00
parent ab088479dd
commit 218082140f
2 changed files with 27 additions and 13 deletions

View File

@ -7,7 +7,6 @@ edition = "2018"
[dependencies] [dependencies]
aabb-quadtree = "0.1.0" aabb-quadtree = "0.1.0"
abstutil = { path = "../abstutil" } abstutil = { path = "../abstutil" }
bimap = { version = "0.3.1", features = ["serde"] }
fast_paths = "0.1.1" fast_paths = "0.1.1"
geom = { path = "../geom" } geom = { path = "../geom" }
gtfs = { path = "../gtfs" } gtfs = { path = "../gtfs" }

View File

@ -1,36 +1,41 @@
use bimap::btree::BiBTreeMap;
use fast_paths::{NodeId, ShortestPath}; use fast_paths::{NodeId, ShortestPath};
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use std::collections::BTreeMap;
// TODO Upstream this in fast_paths when this is more solid. // TODO Upstream this in fast_paths when this is more solid.
#[derive(Serialize)] #[derive(Serialize)]
pub struct NodeMap<T: Copy + Ord + Serialize> { pub struct NodeMap<T: Copy + Ord + Serialize> {
// BiBTreeMap will serialize deterministically, so use it instead of the BiHashMap. #[serde(skip_serializing)]
// TODO Since NodeId is just a usize, maybe have Vec<T> and BTreeMap<T, NodeId> instead of a node_to_id: BTreeMap<T, NodeId>,
// dependency on bimap. id_to_node: Vec<T>,
nodes: BiBTreeMap<T, NodeId>,
} }
impl<T: Copy + Ord + Serialize> NodeMap<T> { impl<T: Copy + Ord + Serialize> NodeMap<T> {
pub fn new() -> NodeMap<T> { pub fn new() -> NodeMap<T> {
NodeMap { NodeMap {
nodes: BiBTreeMap::new(), node_to_id: BTreeMap::new(),
id_to_node: Vec::new(),
} }
} }
pub fn get_or_insert(&mut self, node: T) -> NodeId { pub fn get_or_insert(&mut self, node: T) -> NodeId {
let _ = self.nodes.insert_no_overwrite(node, self.nodes.len()); if let Some(id) = self.node_to_id.get(&node) {
*self.nodes.get_by_left(&node).unwrap() return *id;
}
let id = self.id_to_node.len();
self.node_to_id.insert(node, id);
self.id_to_node.push(node);
id
} }
pub fn get(&self, node: T) -> NodeId { pub fn get(&self, node: T) -> NodeId {
*self.nodes.get_by_left(&node).unwrap() self.node_to_id[&node]
} }
pub fn translate(&self, path: &ShortestPath) -> Vec<T> { pub fn translate(&self, path: &ShortestPath) -> Vec<T> {
path.get_nodes() path.get_nodes()
.iter() .iter()
.map(|id| *self.nodes.get_by_right(id).unwrap()) .map(|id| self.id_to_node[*id])
.collect() .collect()
} }
} }
@ -43,6 +48,16 @@ pub fn deserialize_nodemap<
>( >(
d: D, d: D,
) -> Result<NodeMap<T>, D::Error> { ) -> Result<NodeMap<T>, D::Error> {
let nodes = <BiBTreeMap<T, NodeId>>::deserialize(d)?; // TODO I'm offline and can't look up hw to use Deserializer twice in sequence. Since the two
Ok(NodeMap { nodes }) // fields are redundant, just serialize one of them.
let id_to_node = <Vec<T>>::deserialize(d)?;
let mut node_to_id = BTreeMap::new();
for (id, node) in id_to_node.iter().enumerate() {
node_to_id.insert(*node, id);
}
Ok(NodeMap {
node_to_id,
id_to_node,
})
} }