From a7b3e4b745e00635e1734f9f1b2b3b94a16466e6 Mon Sep 17 00:00:00 2001 From: Patrick Marsee Date: Wed, 16 Apr 2025 23:05:23 -0400 Subject: [PATCH] Changed segment container from Vec to HashMap. --- src/rail_graph.rs | 119 +++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 76 deletions(-) diff --git a/src/rail_graph.rs b/src/rail_graph.rs index a93ecb5..1e1c136 100644 --- a/src/rail_graph.rs +++ b/src/rail_graph.rs @@ -3,8 +3,8 @@ use crate::rail_segment; use crate::rail_segment::RailSegment; use crate::rail_connector::RailConnector; use crate::graph_coord::GraphCoord; -//use std::collections::HashMap; -use std::vec::Vec; +use std::collections::HashMap; +//use std::vec::Vec; //use std::string::String; use std::error; use std::fmt; @@ -27,7 +27,7 @@ impl fmt::Display for Error { impl error::Error for Error {} pub struct RailGraph { - segments: Vec>>, + segments: HashMap>, // segment_names: HashMap, min_available_index: usize, @@ -36,7 +36,7 @@ pub struct RailGraph { impl RailGraph { pub fn new() -> Self { Self { - segments: Vec::>>::new(), + segments: HashMap::>::new(), //segment_names: {}, min_available_index: 0, } @@ -45,34 +45,26 @@ impl RailGraph { // definition pub fn get_segment(&self, index: usize) -> Result<&Box, Error> { - match &self.segments.get(index) { - Some(Some(ret)) => Ok(ret), - _ => Err(Error::IndexError(index)), + match &self.segments.get(&index) { + Some(ret) => Ok(ret), + _ => Err(Error::IndexError(index)), } } pub fn add_segment(&mut self, segment: Box) -> usize { let ret = self.min_available_index; - if self.segments.len() == self.min_available_index { - self.segments.push(Some(segment)); - self.min_available_index = self.segments.len(); - } else { - self.segments[self.min_available_index] = Some(segment); - self.update_min_available_index(); - } + self.segments.insert(ret, segment); + self.min_available_index += 1; ret } pub fn remove_segment(&mut self, index: usize) -> Result { - if index >= self.segments.len() { + if !self.validate_index(index) { return Err(Error::IndexError(index)); } self.isolate_segment(index); - self.segments[index] = Option::None; - if index < self.min_available_index { - self.min_available_index = index; - } + self.segments.remove(&index); Ok(true) } @@ -95,56 +87,47 @@ impl RailGraph { let old_connection1 = self.get_connection_from_index(index1, endpoint1); let old_connection2 = self.get_connection_from_index(index2, endpoint2); if let Ok(old_connection) = old_connection1 { - match &mut self.segments[old_connection.segment_index] { + match self.segments.get_mut(&old_connection.segment_index) { Some(old_segment) => { if let Err(e) = old_segment.remove_connection(old_connection.endpoint_index) { return Err(Error::SegmentError(e)); } }, - None => { + None => { return Err(Error::IndexError(old_connection.segment_index)); - } + }, } } if let Ok(old_connection) = old_connection2 { - match &mut self.segments[old_connection.segment_index] { + match self.segments.get_mut(&old_connection.segment_index) { Some(old_segment) => { if let Err(e) = old_segment.remove_connection(old_connection.endpoint_index) { return Err(Error::SegmentError(e)); } }, - None => { + None => { return Err(Error::IndexError(old_connection.segment_index)); - } + }, } } // Connect them now - let segment1 = &mut self.segments[index1].as_mut().unwrap(); + let segment1 = self.segments.get_mut(&index1).unwrap(); let _ = segment1.add_connection(endpoint1, connector1); - let segment2 = &mut self.segments[index2].as_mut().unwrap(); + let segment2 = self.segments.get_mut(&index2).unwrap(); let _ = segment2.add_connection(endpoint2, connector2); - - //if let Some(segment1) = &mut self.segments[index1] { - // if let Err(e) = segment1.add_connection(endpoint1, connector1) { - // return Err(Error::SegmentError(e)); - // } - //} - //if let Some(segment2) = &mut self.segments[index2] { - // if let Err(e) = segment2.add_connection(endpoint2, connector2) { - // return Err(Error::SegmentError(e)); - // } - //} Ok(true) } pub fn disconnect_endpoint(&mut self, index: usize, endpoint: usize) -> Result { - if index >= self.segments.len() { + if !self.validate_index(index) { return Err(Error::IndexError(index)); + } else if !self.validate_endpoint(index, endpoint) { + return Err(Error::SegmentError(rail_segment::Error::EndpointError(endpoint))); } match self.get_connection_from_index(index, endpoint) { Ok(old_connection) => { - match &mut self.segments[old_connection.segment_index] { + match self.segments.get_mut(&old_connection.segment_index) { Some(old_segment) => { if let Err(e) = old_segment.remove_connection(old_connection.endpoint_index) { return Err(Error::SegmentError(e)); @@ -160,13 +143,10 @@ impl RailGraph { }, } - if let Some(segment) = &mut self.segments[index] { - match segment.remove_connection(endpoint) { - Ok(_) => Ok(true), - Err(e) => Err(Error::SegmentError(e)), - } - } else { - Err(Error::IndexError(index)) // should never happen since this is already tested in the big match block. + let segment = self.segments.get_mut(&index).unwrap(); + match segment.remove_connection(endpoint) { + Ok(_) => Ok(true), + Err(e) => Err(Error::SegmentError(e)), } } @@ -224,21 +204,18 @@ impl RailGraph { // private fn validate_index(&self, index: usize) -> bool { - match &self.segments.get(index) { - Some(Some(_)) => true, - _ => false, - } + self.segments.contains_key(&index) } fn validate_endpoint(&self, index: usize, endpoint: usize) -> bool { - match self.get_segment(index) { - Ok(segment) => { + match &self.segments.get(&index) { + Some(segment) => { match segment.check_connection(endpoint) { Err(rail_segment::Error::EndpointError(_)) => false, _ => true, } }, - Err(_) => false, + None => false, } } @@ -250,39 +227,29 @@ impl RailGraph { } fn get_connection_from_index(&self, index: usize, endpoint: usize) -> Result { - match self.get_segment(index) { - Ok(segment) => Self::get_connection_from_segment(segment, endpoint), - Err(e) => Err(e), + match &self.segments.get(&index) { + Some(segment) => Self::get_connection_from_segment(segment, endpoint), + None => Err(Error::IndexError(index)), } } fn isolate_segment(&mut self, index: usize) { // Get the old connections let mut connections = Vec::::new(); - if let Some(segment) = &self.segments[index] { - for connection in segment.connection_iter() { - connections.push(*connection); - } + let segment = &self.segments[&index]; + for connection in segment.connection_iter() { + connections.push(*connection); } // disconnect neighbors for connection in connections { - if let Some(old_segment) = &mut self.segments[connection.segment_index] { - let _ = old_segment.remove_connection(connection.endpoint_index); - } + let old_segment = self.segments.get_mut(&connection.segment_index).unwrap(); + let _ = old_segment.remove_connection(connection.endpoint_index); } // reflect the same change in the original segment. - if let Some(segment) = &mut self.segments[index] { - segment.remove_all_connections(); - } - } - - fn update_min_available_index(&mut self) { - // I should just replace this with a heap. - while let Some(_segment) = &self.segments[self.min_available_index] { - self.min_available_index += 1; - } + let segment = self.segments.get_mut(&index).unwrap(); + segment.remove_all_connections(); } // Difference from the public version: offset is relative to the segment. @@ -440,8 +407,8 @@ mod tests { // test successes assert!(match test_graph.remove_segment(1) { Ok(true)=>true, _=>false, }, "Segment was not removed."); - assert_eq!(test_graph.segments.len(), 3, "Graph has incorrect number of segments."); - assert_eq!(test_graph.min_available_index, 1, "Incorrect min_available_index."); + assert_eq!(test_graph.segments.len(), 2, "Graph has incorrect number of segments."); + assert_eq!(test_graph.min_available_index, 3, "Incorrect min_available_index."); let first_segment = test_graph.get_segment(0).unwrap(); assert!(!first_segment.check_connection(1).unwrap(), "Connection 1 wasn't broken."); let second_segment = test_graph.get_segment(2).unwrap();