diff --git a/crates/specctra-core/src/mesadata.rs b/crates/specctra-core/src/mesadata.rs index cef56d4..dd51d27 100644 --- a/crates/specctra-core/src/mesadata.rs +++ b/crates/specctra-core/src/mesadata.rs @@ -5,8 +5,8 @@ //! Module for handling Specctra's mesadata - design rules, as well as layers //! or net properties -use bimap::BiHashMap; -use std::collections::HashMap; +use bimap::BiBTreeMap; +use std::collections::BTreeMap; use crate::{ rules::{AccessRules, Conditions}, @@ -74,22 +74,22 @@ pub struct SpecctraMesadata { // net class name -> rule /// A map from net class names to their specific `SpecctraRule` constraints. /// These rules are applied to all nets belonging to the respective net clas - class_rules: HashMap, + class_rules: BTreeMap, // layername <-> layer for Layout /// A bidirectional map between layer indices and layer names, allowing translation /// between index-based layers in the layout and user-defined layer names. - pub layer_layername: BiHashMap, + pub layer_layername: BiBTreeMap, // netname <-> net for Layout /// A bidirectional map between network indices and network names in the PCB layout, /// providing an easy way to reference nets by name or index. - pub net_netname: BiHashMap, + pub net_netname: BiBTreeMap, // net -> netclass /// A map that associates network indices with their respective net class names. /// This is used to apply net class-specific routing rules to each net. - net_netclass: HashMap, + net_netclass: BTreeMap, } impl SpecctraMesadata { @@ -98,7 +98,7 @@ impl SpecctraMesadata { /// This function extracts the necessary metadata from the `Pcb` struct, such as /// layer-to-layer name mappings, net-to-net name mappings, and net class rules. pub fn from_pcb(pcb: &Pcb) -> Self { - let layer_layername = BiHashMap::from_iter( + let layer_layername = BiBTreeMap::from_iter( pcb.structure .layers .iter() @@ -119,11 +119,11 @@ impl SpecctraMesadata { tmp.sort_unstable(); tmp.dedup(); - BiHashMap::from_iter(tmp.into_iter().cloned().enumerate()) + BiBTreeMap::from_iter(tmp.into_iter().cloned().enumerate()) }; - let mut net_netclass = HashMap::new(); - let class_rules = HashMap::from_iter( + let mut net_netclass = BTreeMap::new(); + let class_rules = BTreeMap::from_iter( pcb.network .classes .iter() diff --git a/crates/topola-egui/src/config.rs b/crates/topola-egui/src/config.rs index ca361b8..84cef2c 100644 --- a/crates/topola-egui/src/config.rs +++ b/crates/topola-egui/src/config.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::collections::HashMap; +use std::collections::BTreeMap; #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(default)] @@ -28,7 +28,7 @@ pub struct Colors { #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] pub struct LayerColors { default: LayerColor, - colors: HashMap, + colors: BTreeMap, } impl LayerColors { @@ -54,7 +54,7 @@ impl Default for Config { normal: egui::Color32::from_rgb(255, 255, 255), highlighted: egui::Color32::from_rgb(255, 255, 255), }, - colors: HashMap::from([ + colors: BTreeMap::from([ ( "F.Cu".to_string(), LayerColor { @@ -106,7 +106,7 @@ impl Default for Config { normal: egui::Color32::from_rgb(0, 0, 0), highlighted: egui::Color32::from_rgb(0, 0, 0), }, - colors: HashMap::from([ + colors: BTreeMap::from([ ( "F.Cu".to_string(), LayerColor { diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 14cecaf..6b7b1dc 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -7,7 +7,7 @@ //! structures for representing graph nodes and edges with associated metadata, //! as well as functions for constructing and manipulating these graphs. -use std::collections::HashMap; +use std::collections::BTreeMap; use enum_dispatch::enum_dispatch; use geo::Point; @@ -27,7 +27,7 @@ use crate::{ primitive::MakePrimitiveShape, rules::AccessRules, }, - geometry::{compound::ManageCompounds, shape::AccessShape}, + geometry::shape::AccessShape, graph::{GenericIndex, GetPetgraphIndex}, layout::{ poly::{MakePolyShape, PolyWeight}, @@ -92,7 +92,7 @@ impl Ratsnest { graph: UnGraph::default(), }; - let mut triangulations = HashMap::new(); + let mut triangulations = BTreeMap::new(); let node_bound = layout.drawing().geometry().graph().node_bound(); for layer in 0..layout.drawing().layer_count() { diff --git a/src/autorouter/selection.rs b/src/autorouter/selection.rs index f378bf0..8b8fb01 100644 --- a/src/autorouter/selection.rs +++ b/src/autorouter/selection.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::collections::HashSet; +use std::collections::BTreeSet; use rstar::AABB; use serde::{Deserialize, Serialize}; @@ -10,12 +10,12 @@ use serde::{Deserialize, Serialize}; use crate::{ board::{mesadata::AccessMesadata, BandName, Board}, drawing::graph::{GetLayer, MakePrimitive, PrimitiveIndex}, - geometry::{compound::ManageCompounds, GenericNode}, + geometry::GenericNode, graph::{GenericIndex, GetPetgraphIndex}, layout::{poly::PolyWeight, CompoundWeight, NodeIndex}, }; -#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub struct PinSelector { pub pin: String, pub layer: String, @@ -58,7 +58,7 @@ impl PinSelector { } #[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct PinSelection(HashSet); +pub struct PinSelection(BTreeSet); impl PinSelection { pub fn new() -> Self { @@ -87,7 +87,7 @@ impl PinSelection { } } -#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub struct BandSelector { pub band: BandName, } @@ -118,7 +118,7 @@ impl BandSelector { } #[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct BandSelection(HashSet); +pub struct BandSelection(BTreeSet); impl BandSelection { pub fn new() -> Self { diff --git a/src/board/mod.rs b/src/board/mod.rs index 8916e59..d1f0fe9 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -10,9 +10,9 @@ pub mod mesadata { pub use specctra_core::mesadata::AccessMesadata; } -use std::{cmp::Ordering, collections::HashMap}; +use std::{cmp::Ordering, collections::BTreeMap}; -use bimap::BiHashMap; +use bimap::BiBTreeMap; use derive_getters::Getters; use serde::{Deserialize, Serialize}; @@ -35,7 +35,7 @@ use crate::{ }; /// Represents a band between two pins. -#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialOrd, Ord, PartialEq, Serialize)] pub struct BandName(String, String); impl BandName { @@ -60,9 +60,9 @@ pub struct Board { layout: Layout, // TODO: Simplify access logic to these members so that `#[getter(skip)]`s can be removed. #[getter(skip)] - node_to_pinname: HashMap, + node_to_pinname: BTreeMap, #[getter(skip)] - band_bandname: BiHashMap, + band_bandname: BiBTreeMap, } impl Board { @@ -70,8 +70,8 @@ impl Board { pub fn new(layout: Layout) -> Self { Self { layout, - node_to_pinname: HashMap::new(), - band_bandname: BiHashMap::new(), + node_to_pinname: BTreeMap::new(), + band_bandname: BiBTreeMap::new(), } } diff --git a/src/drawing/band.rs b/src/drawing/band.rs index 025ad09..6e3af7e 100644 --- a/src/drawing/band.rs +++ b/src/drawing/band.rs @@ -2,9 +2,6 @@ // // SPDX-License-Identifier: MIT -// FIXME (implement Hash for BandUid and such) -#![allow(clippy::derived_hash_with_manual_eq)] - use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; @@ -22,7 +19,7 @@ use super::{ Drawing, }; -#[derive(Debug, Hash, Clone, Copy)] +#[derive(Clone, Copy, Debug, Ord, PartialOrd)] pub struct BandUid(pub BandTermsegIndex, pub BandTermsegIndex); impl BandUid { @@ -45,7 +42,7 @@ impl PartialEq for BandUid { impl Eq for BandUid {} #[enum_dispatch(GetPetgraphIndex)] -#[derive(Debug, Hash, Clone, Copy)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum BandTermsegIndex { Straight(LoneLooseSegIndex), Bended(SeqLooseSegIndex), diff --git a/src/drawing/bend.rs b/src/drawing/bend.rs index e98a875..119d9b3 100644 --- a/src/drawing/bend.rs +++ b/src/drawing/bend.rs @@ -18,7 +18,7 @@ use crate::{ use petgraph::stable_graph::NodeIndex; #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum BendIndex { Fixed(FixedBendIndex), Loose(LooseBendIndex), diff --git a/src/drawing/dot.rs b/src/drawing/dot.rs index 169b40e..f48925d 100644 --- a/src/drawing/dot.rs +++ b/src/drawing/dot.rs @@ -20,7 +20,7 @@ use crate::{ }; #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum DotIndex { Fixed(FixedDotIndex), Loose(LooseDotIndex), diff --git a/src/drawing/graph.rs b/src/drawing/graph.rs index 3ecfdde..42c10fe 100644 --- a/src/drawing/graph.rs +++ b/src/drawing/graph.rs @@ -89,7 +89,7 @@ macro_rules! impl_loose_weight { // TODO: This enum shouldn't exist: we shouldn't be carrying the tag around like this. Instead we // should be getting it from the graph when it's needed. #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum PrimitiveIndex { FixedDot(FixedDotIndex), LooseDot(LooseDotIndex), diff --git a/src/drawing/seg.rs b/src/drawing/seg.rs index 0aebdf2..5d35507 100644 --- a/src/drawing/seg.rs +++ b/src/drawing/seg.rs @@ -18,7 +18,7 @@ use crate::{ use petgraph::stable_graph::NodeIndex; #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum SegIndex { Fixed(FixedSegIndex), LoneLoose(LoneLooseSegIndex), diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 2e9e1f4..a2013f4 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::{collections::HashMap, hash::Hash, marker::PhantomData}; +use std::{collections::BTreeMap, marker::PhantomData}; use crate::{ drawing::graph::{GetLayer, Retag}, @@ -17,10 +17,10 @@ pub trait ApplyGeometryEdit< SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, - PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, - DI: GetPetgraphIndex + Into + Eq + Hash + Copy, - SI: GetPetgraphIndex + Into + Eq + Hash + Copy, - BI: GetPetgraphIndex + Into + Eq + Hash + Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, + DI: GetPetgraphIndex + Into + Eq + Ord + Copy, + SI: GetPetgraphIndex + Into + Eq + Ord + Copy, + BI: GetPetgraphIndex + Into + Eq + Ord + Copy, > { fn apply(&mut self, edit: &GeometryEdit); @@ -28,10 +28,11 @@ pub trait ApplyGeometryEdit< #[derive(Debug, Clone)] pub struct GeometryEdit { - pub(super) dots: HashMap, Option)>, - pub(super) segs: HashMap, Option<((DI, DI), SW)>)>, - pub(super) bends: HashMap, Option<((DI, DI, DI), BW)>)>, - pub(super) compounds: HashMap, (Option<(Vec, CW)>, Option<(Vec, CW)>)>, + pub(super) dots: BTreeMap, Option)>, + pub(super) segs: BTreeMap, Option<((DI, DI), SW)>)>, + pub(super) bends: BTreeMap, Option<((DI, DI, DI), BW)>)>, + pub(super) compounds: + BTreeMap, (Option<(Vec, CW)>, Option<(Vec, CW)>)>, primitive_weight_marker: PhantomData, } @@ -41,18 +42,18 @@ impl< SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, - PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, - DI: GetPetgraphIndex + Into + Eq + Hash + Copy, - SI: GetPetgraphIndex + Into + Eq + Hash + Copy, - BI: GetPetgraphIndex + Into + Eq + Hash + Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, + DI: GetPetgraphIndex + Into + Eq + Ord + Copy, + SI: GetPetgraphIndex + Into + Eq + Ord + Copy, + BI: GetPetgraphIndex + Into + Eq + Ord + Copy, > GeometryEdit { pub fn new() -> Self { Self { - dots: HashMap::new(), - segs: HashMap::new(), - bends: HashMap::new(), - compounds: HashMap::new(), + dots: BTreeMap::new(), + segs: BTreeMap::new(), + bends: BTreeMap::new(), + compounds: BTreeMap::new(), primitive_weight_marker: PhantomData, } } diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index 5846bb5..8bdda13 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -64,7 +64,7 @@ pub enum GeometryLabel { Compound, } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub enum GenericNode { Primitive(P), Compound(C), diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index 39903f6..ab213ee 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::collections::hash_map::Entry as HashMapEntry; -use std::hash::Hash; +use std::collections::btree_map::Entry as BTreeMapEntry; use geo::Point; use petgraph::stable_graph::StableDiGraph; @@ -33,10 +32,10 @@ impl< SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, - PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, - DI: GetPetgraphIndex + Into + Eq + Hash + Copy, - SI: GetPetgraphIndex + Into + Eq + Hash + Copy, - BI: GetPetgraphIndex + Into + Eq + Hash + Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, + DI: GetPetgraphIndex + Into + Eq + Ord + Copy, + SI: GetPetgraphIndex + Into + Eq + Ord + Copy, + BI: GetPetgraphIndex + Into + Eq + Ord + Copy, > RecordingGeometryWithRtree { pub fn new(layer_count: usize) -> Self { @@ -316,23 +315,23 @@ impl< } } -fn edit_remove_from_map( - map: &mut std::collections::HashMap, Option)>, +fn edit_remove_from_map( + map: &mut std::collections::BTreeMap, Option)>, index: I, data: T, ) where - I: core::cmp::Eq + Hash, + I: core::cmp::Eq + Ord, { let to_be_inserted = (Some(data), None); match map.entry(index) { - HashMapEntry::Occupied(mut occ) => { + BTreeMapEntry::Occupied(mut occ) => { if let (None, Some(_)) = occ.get() { occ.remove(); } else { *occ.get_mut() = to_be_inserted; } } - HashMapEntry::Vacant(vac) => { + BTreeMapEntry::Vacant(vac) => { vac.insert(to_be_inserted); } } @@ -344,10 +343,10 @@ impl< SW: AccessSegWeight + GetLayer, BW: AccessBendWeight + GetLayer, CW: Copy, - PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Hash + Copy, - DI: GetPetgraphIndex + Into + Eq + Hash + Copy, - SI: GetPetgraphIndex + Into + Eq + Hash + Copy, - BI: GetPetgraphIndex + Into + Eq + Hash + Copy, + PI: GetPetgraphIndex + TryInto + TryInto + TryInto + Eq + Ord + Copy, + DI: GetPetgraphIndex + Into + Eq + Ord + Copy, + SI: GetPetgraphIndex + Into + Eq + Ord + Copy, + BI: GetPetgraphIndex + Into + Eq + Ord + Copy, > ApplyGeometryEdit for RecordingGeometryWithRtree { diff --git a/src/graph.rs b/src/graph.rs index 492d5e1..d0ed84d 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -2,10 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::{ - hash::{Hash, Hasher}, - marker::PhantomData, -}; +use std::{cmp::Ordering, marker::PhantomData}; use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; @@ -50,6 +47,8 @@ impl core::clone::Clone for GenericIndex { } } +impl core::marker::Copy for GenericIndex {} + impl core::fmt::Debug for GenericIndex { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("GenericIndex") @@ -65,12 +64,17 @@ impl PartialEq for GenericIndex { } } -impl core::marker::Copy for GenericIndex {} impl Eq for GenericIndex {} -impl Hash for GenericIndex { - fn hash(&self, state: &mut H) { - self.node_index.hash(state) +impl PartialOrd for GenericIndex { + fn partial_cmp(&self, other: &Self) -> Option { + self.node_index.partial_cmp(&other.node_index) + } +} + +impl Ord for GenericIndex { + fn cmp(&self, other: &Self) -> Ordering { + self.node_index.cmp(&other.node_index) } } diff --git a/src/router/astar.rs b/src/router/astar.rs index f50b81b..5886c7e 100644 --- a/src/router/astar.rs +++ b/src/router/astar.rs @@ -3,10 +3,8 @@ // // SPDX-License-Identifier: MIT -use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::collections::{BinaryHeap, HashMap, VecDeque}; +use std::collections::{btree_map::Entry, BTreeMap, BinaryHeap, VecDeque}; -use std::hash::Hash; use std::ops::ControlFlow; use petgraph::algo::Measure; @@ -63,19 +61,19 @@ impl Ord for MinScored { pub struct PathTracker where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, { - came_from: HashMap, + came_from: BTreeMap, } impl PathTracker where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, { fn new() -> PathTracker { PathTracker { - came_from: HashMap::new(), + came_from: BTreeMap::new(), } } @@ -101,7 +99,7 @@ where pub trait AstarStrategy where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, for<'a> &'a G: IntoEdges + MakeEdgeRef, K: Measure + Copy, { @@ -122,14 +120,14 @@ pub trait MakeEdgeRef: IntoEdgeReferences { pub struct Astar where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, for<'a> &'a G: IntoEdges + MakeEdgeRef, K: Measure + Copy, { pub graph: G, pub visit_next: BinaryHeap>, - pub scores: HashMap, - pub estimate_scores: HashMap, + pub scores: BTreeMap, + pub estimate_scores: BTreeMap, pub path_tracker: PathTracker, pub maybe_curr_node: Option, // FIXME: To work around edge references borrowing from the graph we collect then reiterate over tem. @@ -154,7 +152,7 @@ pub enum AstarError { impl Astar where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, for<'a> &'a G: IntoEdges + MakeEdgeRef, K: Measure + Copy, { @@ -162,8 +160,8 @@ where let mut this = Self { graph, visit_next: BinaryHeap::new(), - scores: HashMap::new(), - estimate_scores: HashMap::new(), + scores: BTreeMap::new(), + estimate_scores: BTreeMap::new(), path_tracker: PathTracker::::new(), maybe_curr_node: None, edge_ids: VecDeque::new(), @@ -182,7 +180,7 @@ impl> Step, R), AstarCo for Astar where G: GraphBase, - G::NodeId: Eq + Hash, + G::NodeId: Eq + Ord, for<'a> &'a G: IntoEdges + MakeEdgeRef, K: Measure + Copy, { @@ -209,7 +207,7 @@ where let next_score = node_score + edge_cost; match self.scores.entry(next) { - Occupied(mut entry) => { + Entry::Occupied(mut entry) => { // No need to add neighbors that we have already reached through a // shorter path than now. if *entry.get() <= next_score { @@ -217,7 +215,7 @@ where } entry.insert(next_score); } - Vacant(entry) => { + Entry::Vacant(entry) => { entry.insert(next_score); } } @@ -248,7 +246,7 @@ where } match self.estimate_scores.entry(node) { - Occupied(mut entry) => { + Entry::Occupied(mut entry) => { // If the node has already been visited with an equal or lower score than // now, then we do not need to re-visit it. if *entry.get() <= estimate_score { @@ -256,7 +254,7 @@ where } entry.insert(estimate_score); } - Vacant(entry) => { + Entry::Vacant(entry) => { entry.insert(estimate_score); } } diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index 952719f..a4d3195 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::collections::HashMap; +use std::collections::BTreeMap; use enum_dispatch::enum_dispatch; use geo::Point; @@ -37,7 +37,7 @@ use crate::{ use super::RouterOptions; -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct NavvertexIndex(NodeIndex); impl GetPetgraphIndex for NavvertexIndex { @@ -50,7 +50,7 @@ impl GetPetgraphIndex for NavvertexIndex { /// counterclockwise. Unlike their constituents, binavvertices are themselves /// not considered navvertices. #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BinavvertexNodeIndex { FixedDot(FixedDotIndex), FixedBend(FixedBendIndex), @@ -84,7 +84,7 @@ impl From for GearIndex { /// /// The name "trianvertex" is a shortening of "triangulation vertex". #[enum_dispatch(GetPetgraphIndex, MakePrimitive)] -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] enum TrianvertexNodeIndex { FixedDot(FixedDotIndex), FixedBend(FixedBendIndex), @@ -210,8 +210,7 @@ impl Navmesh { let mut origin_navvertex = None; let mut destination_navvertex = None; - // `HashMap` is obviously suboptimal here. - let mut map = HashMap::new(); + let mut map = BTreeMap::new(); for trianvertex in triangulation.node_identifiers() { if trianvertex == origin.into() { @@ -302,7 +301,7 @@ impl Navmesh { fn add_node_to_graph_and_map_as_binavvertex( graph: &mut UnGraph, - map: &mut HashMap, NodeIndex)>>, + map: &mut BTreeMap, NodeIndex)>>, trianvertex: TrianvertexNodeIndex, node: BinavvertexNodeIndex, ) { diff --git a/src/specctra/design.rs b/src/specctra/design.rs index 14fd348..97e764e 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -6,8 +6,9 @@ //! Design DSN file, creating the [`Board`] object from the file, as well as //! exporting the session file +use std::collections::{btree_map::Entry as BTreeMapEntry, BTreeMap}; + use geo::{point, Point, Rotate}; -use std::collections::{hash_map::Entry as HashMapEntry, HashMap}; use crate::{ board::{mesadata::AccessMesadata, Board}, @@ -73,7 +74,7 @@ impl SpecctraDesign { let mesadata = board.mesadata(); let drawing = board.layout().drawing(); - let mut net_outs = HashMap::::new(); + let mut net_outs = BTreeMap::::new(); for index in drawing.primitive_nodes() { let primitive = index.primitive(drawing); @@ -131,8 +132,8 @@ impl SpecctraDesign { }; let net_out = match net_outs.entry(net) { - HashMapEntry::Occupied(occ) => occ.into_mut(), - HashMapEntry::Vacant(vac) => vac.insert(structure::NetOut { + BTreeMapEntry::Occupied(occ) => occ.into_mut(), + BTreeMapEntry::Vacant(vac) => vac.insert(structure::NetOut { name: mesadata .net_netname(net) .ok_or_else(|| { @@ -208,7 +209,7 @@ impl SpecctraDesign { }) // flatten the nested iters into a single stream of tuples .flatten() - .collect::>(); + .collect::>(); // add pins from components for component in &self.pcb.placement.components {