From 218082140faddcfac10ee4125d3d724bc3ecc9a7 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 27 Jun 2019 10:00:20 -0700 Subject: [PATCH] don't use a bimap for NodeMap. less dependencies, marginal speed boost --- map_model/Cargo.toml | 1 - map_model/src/pathfind/node_map.rs | 39 +++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/map_model/Cargo.toml b/map_model/Cargo.toml index 36dfd3e7b2..a4fd98b1f7 100644 --- a/map_model/Cargo.toml +++ b/map_model/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [dependencies] aabb-quadtree = "0.1.0" abstutil = { path = "../abstutil" } -bimap = { version = "0.3.1", features = ["serde"] } fast_paths = "0.1.1" geom = { path = "../geom" } gtfs = { path = "../gtfs" } diff --git a/map_model/src/pathfind/node_map.rs b/map_model/src/pathfind/node_map.rs index 38d14df287..d27a15c0d8 100644 --- a/map_model/src/pathfind/node_map.rs +++ b/map_model/src/pathfind/node_map.rs @@ -1,36 +1,41 @@ -use bimap::btree::BiBTreeMap; use fast_paths::{NodeId, ShortestPath}; use serde::{Deserialize, Deserializer, Serialize}; +use std::collections::BTreeMap; // TODO Upstream this in fast_paths when this is more solid. #[derive(Serialize)] pub struct NodeMap { - // BiBTreeMap will serialize deterministically, so use it instead of the BiHashMap. - // TODO Since NodeId is just a usize, maybe have Vec and BTreeMap instead of a - // dependency on bimap. - nodes: BiBTreeMap, + #[serde(skip_serializing)] + node_to_id: BTreeMap, + id_to_node: Vec, } impl NodeMap { pub fn new() -> 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 { - let _ = self.nodes.insert_no_overwrite(node, self.nodes.len()); - *self.nodes.get_by_left(&node).unwrap() + if let Some(id) = self.node_to_id.get(&node) { + 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 { - *self.nodes.get_by_left(&node).unwrap() + self.node_to_id[&node] } pub fn translate(&self, path: &ShortestPath) -> Vec { path.get_nodes() .iter() - .map(|id| *self.nodes.get_by_right(id).unwrap()) + .map(|id| self.id_to_node[*id]) .collect() } } @@ -43,6 +48,16 @@ pub fn deserialize_nodemap< >( d: D, ) -> Result, D::Error> { - let nodes = >::deserialize(d)?; - Ok(NodeMap { nodes }) + // TODO I'm offline and can't look up hw to use Deserializer twice in sequence. Since the two + // fields are redundant, just serialize one of them. + let id_to_node = >::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, + }) }