@@ -1781,12 +1781,13 @@ pub mod iter {
17811781 }
17821782
17831783 /// A stack that can check contains in roughly O(1) time.
1784- struct Stack < T : std:: hash:: Hash + PartialEq + Eq + Clone > {
1784+ #[ derive( Clone ) ]
1785+ struct Walk < T : std:: hash:: Hash + PartialEq + Eq + Clone > {
17851786 stack : Vec < T > ,
17861787 counter : HashMap < T , usize > ,
17871788 }
17881789
1789- impl < T > Stack < T >
1790+ impl < T > Walk < T >
17901791 where
17911792 T : std:: hash:: Hash + PartialEq + Eq + Clone ,
17921793 {
@@ -1804,24 +1805,14 @@ pub mod iter {
18041805 * self . counter . entry ( item) . or_insert ( 0 ) += 1 ;
18051806 }
18061807
1807- /// Pops the top element from the stack
1808- fn pop ( & mut self ) -> Option < T > {
1809- if let Some ( item) = self . stack . pop ( ) {
1810- if let Some ( count) = self . counter . get_mut ( & item) {
1811- * count -= 1 ;
1812- if * count == 0 {
1813- self . counter . remove ( & item) ;
1814- }
1815- }
1816- Some ( item)
1817- } else {
1818- None
1819- }
1808+ /// Returns true if the stack shows a cycle
1809+ fn contains_cycle ( & self ) -> bool {
1810+ self . counter . values ( ) . any ( |& count| count > 1 )
18201811 }
18211812
1822- /// Checks if the stack contains the given element
1823- fn contains ( & self , item : & T ) -> bool {
1824- self . counter . contains_key ( item )
1813+ /// Returns a reference to the last element in the stack
1814+ fn last ( & self ) -> Option < & T > {
1815+ self . stack . last ( )
18251816 }
18261817 }
18271818
@@ -1845,7 +1836,7 @@ pub mod iter {
18451836 /// ```
18461837 pub struct DFSIterator < ' a , I : Instantiable > {
18471838 netlist : & ' a Netlist < I > ,
1848- stack : Stack < NetRef < I > > ,
1839+ stacks : Vec < Walk < NetRef < I > > > ,
18491840 visited : HashSet < usize > ,
18501841 cycles : bool ,
18511842 }
@@ -1856,11 +1847,11 @@ pub mod iter {
18561847 {
18571848 /// Create a new DFS iterator for the netlist starting at `from`.
18581849 pub fn new ( netlist : & ' a Netlist < I > , from : NetRef < I > ) -> Self {
1859- let mut s = Stack :: new ( ) ;
1850+ let mut s = Walk :: new ( ) ;
18601851 s. push ( from) ;
18611852 Self {
18621853 netlist,
1863- stack : s ,
1854+ stacks : vec ! [ s ] ,
18641855 visited : HashSet :: new ( ) ,
18651856 cycles : false ,
18661857 }
@@ -1899,25 +1890,25 @@ pub mod iter {
18991890 type Item = NetRef < I > ;
19001891
19011892 fn next ( & mut self ) -> Option < Self :: Item > {
1902- if let Some ( item) = self . stack . pop ( ) {
1903- let uw = item. clone ( ) . unwrap ( ) ;
1893+ if let Some ( walk) = self . stacks . pop ( ) {
1894+ let item = walk. last ( ) . cloned ( ) ;
1895+ let uw = item. clone ( ) . unwrap ( ) . unwrap ( ) ;
19041896 let index = uw. borrow ( ) . get_index ( ) ;
19051897 if self . visited . insert ( index) {
19061898 let operands = & uw. borrow ( ) . operands ;
19071899 for operand in operands. iter ( ) . flatten ( ) {
1908- self . stack
1909- . push ( NetRef :: wrap ( self . netlist . index_weak ( & operand. root ( ) ) ) ) ;
1900+ let mut new_walk = walk. clone ( ) ;
1901+ new_walk. push ( NetRef :: wrap ( self . netlist . index_weak ( & operand. root ( ) ) ) ) ;
1902+ if !new_walk. contains_cycle ( ) {
1903+ self . stacks . push ( new_walk) ;
1904+ } else {
1905+ self . cycles = true ;
1906+ }
19101907 }
1911- } else {
1912- self . cycles = true ;
1908+ return item;
19131909 }
19141910
1915- return if self . stack . contains ( & item) {
1916- self . cycles = true ;
1917- self . next ( )
1918- } else {
1919- Some ( item)
1920- } ;
1911+ return self . next ( ) ;
19211912 }
19221913
19231914 None
0 commit comments