mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
fix sim nondet test failure by using BTreeMap in my MultiMap
This commit is contained in:
parent
8d9a44fd76
commit
5f6d7e1b66
@ -7,7 +7,6 @@ edition = "2018"
|
||||
[dependencies]
|
||||
bincode = "1.1.1"
|
||||
lazy_static = "1.1.0"
|
||||
multimap = "0.4.0"
|
||||
procfs = "0.4.4"
|
||||
rand = { version = "0.6.5", features = ["serde1"] }
|
||||
rand_xorshift = "0.1.1"
|
||||
|
@ -1,27 +1,34 @@
|
||||
use std;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::cmp::Ord;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
pub struct MultiMap<K, V> {
|
||||
map: HashMap<K, HashSet<V>>,
|
||||
empty: HashSet<V>,
|
||||
// TODO Ideally derive Serialize and Deserialize, but I can't seem to express the lifetimes
|
||||
// correctly.
|
||||
#[derive(PartialEq)]
|
||||
pub struct MultiMap<K, V>
|
||||
where
|
||||
K: Ord + PartialEq,
|
||||
V: Ord + PartialEq,
|
||||
{
|
||||
map: BTreeMap<K, BTreeSet<V>>,
|
||||
empty: BTreeSet<V>,
|
||||
}
|
||||
|
||||
impl<K, V> MultiMap<K, V>
|
||||
where
|
||||
K: std::cmp::Eq + std::hash::Hash,
|
||||
V: std::cmp::Eq + std::hash::Hash,
|
||||
K: Ord + PartialEq,
|
||||
V: Ord + PartialEq,
|
||||
{
|
||||
pub fn new() -> MultiMap<K, V> {
|
||||
MultiMap {
|
||||
map: HashMap::new(),
|
||||
empty: HashSet::new(),
|
||||
map: BTreeMap::new(),
|
||||
empty: BTreeSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: K, value: V) {
|
||||
self.map
|
||||
.entry(key)
|
||||
.or_insert_with(HashSet::new)
|
||||
.or_insert_with(BTreeSet::new)
|
||||
.insert(value);
|
||||
}
|
||||
|
||||
@ -35,9 +42,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, key: K) -> &HashSet<V> {
|
||||
pub fn get(&self, key: K) -> &BTreeSet<V> {
|
||||
self.map.get(&key).unwrap_or(&self.empty)
|
||||
}
|
||||
|
||||
pub(crate) fn raw_map(&self) -> &BTreeMap<K, BTreeSet<V>> {
|
||||
&self.map
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wraparound_get<T>(vec: &Vec<T>, idx: isize) -> &T {
|
||||
|
@ -1,14 +1,13 @@
|
||||
use crate::time::prettyprint_time;
|
||||
use crate::{elapsed_seconds, prettyprint_usize, Timer, PROGRESS_FREQUENCY_SECONDS};
|
||||
use crate::{elapsed_seconds, prettyprint_usize, MultiMap, Timer, PROGRESS_FREQUENCY_SECONDS};
|
||||
use bincode;
|
||||
use multimap;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_json;
|
||||
use std;
|
||||
use std::cmp::Ord;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fs::File;
|
||||
use std::hash::Hash;
|
||||
use std::io::{stdout, BufReader, BufWriter, Error, ErrorKind, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::time::Instant;
|
||||
@ -80,24 +79,24 @@ pub fn deserialize_btreemap<
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
pub fn serialize_multimap<S: Serializer, K: Serialize + Eq + Hash, V: Serialize + Eq + Hash>(
|
||||
map: &multimap::MultiMap<K, V>,
|
||||
pub fn serialize_multimap<S: Serializer, K: Serialize + Eq + Ord, V: Serialize + Eq + Ord>(
|
||||
map: &MultiMap<K, V>,
|
||||
s: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
// TODO maybe need to sort to have deterministic output
|
||||
map.iter_all().collect::<Vec<(_, _)>>().serialize(s)
|
||||
map.raw_map().iter().collect::<Vec<(_, _)>>().serialize(s)
|
||||
}
|
||||
|
||||
pub fn deserialize_multimap<
|
||||
'de,
|
||||
D: Deserializer<'de>,
|
||||
K: Deserialize<'de> + Eq + Hash + Clone,
|
||||
V: Deserialize<'de> + Eq + Hash,
|
||||
K: Deserialize<'de> + Eq + Ord + Clone,
|
||||
V: Deserialize<'de> + Eq + Ord,
|
||||
>(
|
||||
d: D,
|
||||
) -> Result<multimap::MultiMap<K, V>, D::Error> {
|
||||
) -> Result<MultiMap<K, V>, D::Error> {
|
||||
let vec = <Vec<(K, Vec<V>)>>::deserialize(d)?;
|
||||
let mut map = multimap::MultiMap::new();
|
||||
let mut map = MultiMap::new();
|
||||
for (key, values) in vec {
|
||||
for value in values {
|
||||
map.insert(key.clone(), value);
|
||||
|
@ -15,6 +15,9 @@
|
||||
- easter eggs
|
||||
- name agents, with some good names scattered in (Dustin Carlino, Dustin Bikelino, Dustin Buslino...)
|
||||
|
||||
## More things to simulate
|
||||
|
||||
- Light rail and downtown bus tunnel
|
||||
|
||||
## The very detailed driving model
|
||||
|
||||
|
@ -13,7 +13,6 @@ geom = { path = "../geom" }
|
||||
lazy_static = "1.1.0"
|
||||
map_model = { path = "../map_model" }
|
||||
more-asserts = "0.2.1"
|
||||
multimap = "0.4.0"
|
||||
pretty_assertions = "0.5.1"
|
||||
rand = { version = "0.6.5", features = ["serde1"] }
|
||||
rand_xorshift = "0.1.1"
|
||||
|
@ -1,11 +1,10 @@
|
||||
use crate::{CarID, CarStatus, DrawCarInput, ParkedCar, ParkingSpot, Vehicle, VehicleType};
|
||||
use abstutil::{
|
||||
deserialize_btreemap, deserialize_multimap, serialize_btreemap, serialize_multimap,
|
||||
deserialize_btreemap, deserialize_multimap, serialize_btreemap, serialize_multimap, MultiMap,
|
||||
};
|
||||
use geom::{Angle, Distance, Pt2D};
|
||||
use map_model;
|
||||
use map_model::{BuildingID, Lane, LaneID, LaneType, Map, Position, Traversable};
|
||||
use multimap::MultiMap;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::iter;
|
||||
@ -178,8 +177,7 @@ impl ParkingSimState {
|
||||
|
||||
pub fn get_parked_cars_by_owner(&self, id: BuildingID) -> Vec<&ParkedCar> {
|
||||
self.cars_per_building
|
||||
.get_vec(&id)
|
||||
.unwrap_or(&Vec::new())
|
||||
.get(id)
|
||||
.iter()
|
||||
.map(|id| &self.cars[id])
|
||||
.collect()
|
||||
|
@ -2,10 +2,9 @@ use crate::{
|
||||
AgentID, CreatePedestrian, DistanceInterval, DrawPedestrianInput, IntersectionSimState,
|
||||
ParkingSimState, PedestrianID, Scheduler, SidewalkPOI, SidewalkSpot, TimeInterval, TripManager,
|
||||
};
|
||||
use abstutil::{deserialize_multimap, serialize_multimap};
|
||||
use abstutil::{deserialize_multimap, serialize_multimap, MultiMap};
|
||||
use geom::{Distance, Duration, Line, Speed};
|
||||
use map_model::{BuildingID, Map, Path, PathStep, Trace, Traversable};
|
||||
use multimap::MultiMap;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@ -89,8 +88,7 @@ impl WalkingSimState {
|
||||
map: &Map,
|
||||
) -> Vec<DrawPedestrianInput> {
|
||||
self.peds_per_traversable
|
||||
.get_vec(&on)
|
||||
.unwrap_or(&Vec::new())
|
||||
.get(on)
|
||||
.iter()
|
||||
.map(|id| self.peds[id].get_draw_ped(time, map))
|
||||
.collect()
|
||||
@ -114,10 +112,8 @@ impl WalkingSimState {
|
||||
match ped.goal.connection {
|
||||
SidewalkPOI::ParkingSpot(spot) => {
|
||||
delete.push(ped.id);
|
||||
delete_ped_from_current_step(
|
||||
&mut self.peds_per_traversable,
|
||||
ped,
|
||||
);
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_parking_spot(
|
||||
time, ped.id, spot, map, parking, scheduler,
|
||||
);
|
||||
@ -136,10 +132,8 @@ impl WalkingSimState {
|
||||
}
|
||||
SidewalkPOI::Border(i) => {
|
||||
delete.push(ped.id);
|
||||
delete_ped_from_current_step(
|
||||
&mut self.peds_per_traversable,
|
||||
ped,
|
||||
);
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_border(time, ped.id, i, map);
|
||||
}
|
||||
SidewalkPOI::BikeRack(driving_pos) => {
|
||||
@ -171,7 +165,8 @@ impl WalkingSimState {
|
||||
}
|
||||
}
|
||||
|
||||
delete_ped_from_current_step(&mut self.peds_per_traversable, ped);
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
ped.path.shift();
|
||||
let start_dist = match ped.path.current_step() {
|
||||
PathStep::Lane(_) => Distance::ZERO,
|
||||
@ -196,14 +191,16 @@ impl WalkingSimState {
|
||||
PedState::EnteringBuilding(bldg, ref time_int) => {
|
||||
if time > time_int.end {
|
||||
delete.push(ped.id);
|
||||
delete_ped_from_current_step(&mut self.peds_per_traversable, ped);
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_building(time, ped.id, bldg, map);
|
||||
}
|
||||
}
|
||||
PedState::StartingToBike(ref spot, _, ref time_int) => {
|
||||
if time > time_int.end {
|
||||
delete.push(ped.id);
|
||||
delete_ped_from_current_step(&mut self.peds_per_traversable, ped);
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_ready_to_bike(time, ped.id, spot.clone(), map, scheduler);
|
||||
}
|
||||
}
|
||||
@ -252,13 +249,6 @@ impl WalkingSimState {
|
||||
}
|
||||
}
|
||||
|
||||
fn delete_ped_from_current_step(map: &mut MultiMap<Traversable, PedestrianID>, ped: &Pedestrian) {
|
||||
// API is so bad that we have this helper!
|
||||
map.get_vec_mut(&ped.path.current_step().as_traversable())
|
||||
.unwrap()
|
||||
.retain(|&p| p != ped.id);
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq)]
|
||||
struct Pedestrian {
|
||||
id: PedestrianID,
|
||||
|
Loading…
Reference in New Issue
Block a user