fix sim nondet test failure by using BTreeMap in my MultiMap

This commit is contained in:
Dustin Carlino 2019-03-01 11:40:59 -08:00
parent 8d9a44fd76
commit 5f6d7e1b66
7 changed files with 48 additions and 49 deletions

View File

@ -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"

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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()

View File

@ -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,