mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 04:35:51 +03:00
don't use a bimap for NodeMap. less dependencies, marginal speed boost
This commit is contained in:
parent
ab088479dd
commit
218082140f
@ -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" }
|
||||||
|
@ -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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user