3030//! any time.
3131
3232use std:: collections:: HashMap ;
33- use std:: collections:: VecDeque ;
3433
3534use smallvec:: SmallVec ;
3635
3736use crate :: arena:: Handle ;
37+ use crate :: arena:: List ;
38+ use crate :: arena:: ListArena ;
3839use crate :: graph:: Edge ;
3940use crate :: graph:: Node ;
4041use crate :: graph:: StackGraph ;
4142use crate :: partial:: PartialPath ;
4243use crate :: partial:: PartialPaths ;
43- use crate :: paths:: Extend ;
4444use crate :: paths:: Path ;
4545use crate :: stitching:: Database ;
4646use crate :: stitching:: OwnedOrDatabasePath ;
@@ -140,51 +140,65 @@ where
140140
141141#[ derive( Clone ) ]
142142pub struct EdgeAppendingCycleDetector {
143- edges : VecDeque < Edge > ,
143+ edges : List < Edge > ,
144144}
145145
146- pub struct AppendedEdges { }
147-
148- impl AppendedEdges {
149- pub fn new ( ) -> Self {
150- Self { }
151- }
152- }
146+ pub type AppendedEdges = ListArena < Edge > ;
153147
154148impl EdgeAppendingCycleDetector {
155149 pub fn new ( ) -> Self {
156150 Self {
157- edges : vec ! [ ] . into ( ) ,
151+ edges : List :: empty ( ) ,
158152 }
159153 }
160154
161155 pub fn append_edge (
162156 & mut self ,
163157 graph : & StackGraph ,
164158 partials : & mut PartialPaths ,
165- _edges : & mut AppendedEdges ,
159+ appended_edges : & mut AppendedEdges ,
166160 edge : Edge ,
167161 ) -> Result < ( ) , ( ) > {
168162 let end_node = edge. sink ;
169- self . edges . push ( edge) ;
163+ self . edges . push_front ( appended_edges , edge) ;
170164
171165 let mut cyclic_path = PartialPath :: from_node ( graph, partials, end_node) ;
172- let mut last_idx = self . edges . len ( ) ;
173- for idx in ( 0 ..last_idx) . rev ( ) {
174- let edge = self . edges [ idx] ;
175- if edge. source != cyclic_path. end_node {
176- continue ;
166+ let mut index = self . edges ;
167+ let mut edges = self . edges ;
168+ loop {
169+ // find loop point
170+ let mut count = 0usize ;
171+ loop {
172+ match index. pop_front ( appended_edges) {
173+ Some ( edge) => {
174+ count += 1 ;
175+ if edge. source == end_node {
176+ break ;
177+ }
178+ }
179+ None => return Ok ( ( ) ) ,
180+ }
181+ }
182+
183+ // get prefix edges
184+ let mut prefix_edges = List :: empty ( ) ;
185+ for _ in 0 ..count {
186+ prefix_edges. push_front ( appended_edges, * edges. pop_front ( appended_edges) . unwrap ( ) ) ;
177187 }
178188
179- let mut prefix_path = PartialPath :: from_node ( graph , partials , edge . source ) ;
180- for idx in idx..last_idx {
181- let edge = self . edges [ idx ] ;
189+ // build prefix path
190+ let mut prefix_path = PartialPath :: from_node ( graph , partials , end_node ) ;
191+ while let Some ( edge) = prefix_edges . pop_front ( appended_edges ) {
182192 prefix_path
183193 . resolve_to ( graph, partials, edge. source )
184194 . unwrap ( ) ;
185- prefix_path. append ( graph, partials, edge) . unwrap ( ) ;
195+ prefix_path. append ( graph, partials, * edge) . unwrap ( ) ;
186196 }
187- last_idx = idx;
197+
198+ // build cyclic path
199+ prefix_path
200+ . resolve_to ( graph, partials, cyclic_path. start_node )
201+ . unwrap ( ) ;
188202 prefix_path. ensure_no_overlapping_variables ( partials, & cyclic_path) ;
189203 prefix_path
190204 . concatenate ( graph, partials, & cyclic_path)
@@ -195,8 +209,6 @@ impl EdgeAppendingCycleDetector {
195209 return Err ( ( ) ) ;
196210 }
197211 }
198-
199- Ok ( ( ) )
200212 }
201213}
202214
@@ -205,59 +217,74 @@ impl EdgeAppendingCycleDetector {
205217
206218#[ derive( Clone ) ]
207219pub struct PartialPathAppendingCycleDetector {
208- paths : VecDeque < OwnedOrDatabasePath > ,
220+ paths : List < OwnedOrDatabasePath > ,
209221}
210222
211- pub struct AppendedPartialPaths { }
212-
213- impl AppendedPartialPaths {
214- pub fn new ( ) -> Self {
215- Self { }
216- }
217- }
223+ pub type AppendedPartialPaths = ListArena < OwnedOrDatabasePath > ;
218224
219225impl PartialPathAppendingCycleDetector {
220226 pub fn from_partial_path (
221227 _graph : & StackGraph ,
222228 _partials : & mut PartialPaths ,
223229 _db : & mut Database ,
224- _paths : & mut AppendedPartialPaths ,
230+ appended_paths : & mut AppendedPartialPaths ,
225231 path : OwnedOrDatabasePath ,
226232 ) -> Self {
227- Self {
228- paths : vec ! [ path ] . into ( ) ,
229- }
233+ let mut paths = List :: empty ( ) ;
234+ paths. push_front ( appended_paths , path ) ;
235+ Self { paths }
230236 }
231237
232238 pub fn append_partial_path (
233239 & mut self ,
234240 graph : & StackGraph ,
235241 partials : & mut PartialPaths ,
236242 db : & Database ,
237- _paths : & mut AppendedPartialPaths ,
243+ appended_paths : & mut AppendedPartialPaths ,
238244 path : OwnedOrDatabasePath ,
239245 ) -> Result < ( ) , ( ) > {
240246 let end_node = path. get ( db) . end_node ;
241- self . paths . push ( path) ;
247+ self . paths . push_front ( appended_paths , path) ;
242248
243249 let mut cyclic_path = PartialPath :: from_node ( graph, partials, end_node) ;
244- let mut last_idx = self . paths . len ( ) ;
245- for idx in ( 0 ..last_idx) . rev ( ) {
246- let path = self . paths [ idx] . get ( db) ;
247- if path. start_node != cyclic_path. end_node {
248- continue ;
250+ let mut index = self . paths ;
251+ let mut paths = self . paths ;
252+ loop {
253+ // find loop point
254+ let mut count = 0usize ;
255+ loop {
256+ match index. pop_front ( appended_paths) {
257+ Some ( path) => {
258+ count += 1 ;
259+ if path. get ( db) . start_node == end_node {
260+ break ;
261+ }
262+ }
263+ None => return Ok ( ( ) ) ,
264+ }
265+ }
266+
267+ // get prefix paths
268+ let mut prefix_paths = List :: empty ( ) ;
269+ for _ in 0 ..count {
270+ prefix_paths. push_front (
271+ appended_paths,
272+ paths. pop_front ( appended_paths) . unwrap ( ) . clone ( ) ,
273+ ) ;
249274 }
250275
251- let mut prefix_path = path. clone ( ) ;
252- for idx in ( idx + 1 ) ..last_idx {
253- let path = self . paths [ idx] . get ( db) ;
276+ // build prefix path
277+ let mut prefix_path = PartialPath :: from_node ( graph, partials, end_node) ;
278+ while let Some ( path) = prefix_paths. pop_front ( appended_paths) {
279+ let path = path. get ( db) ;
254280 prefix_path
255281 . resolve_to ( graph, partials, path. start_node )
256282 . unwrap ( ) ;
257283 prefix_path. ensure_no_overlapping_variables ( partials, path) ;
258284 prefix_path. concatenate ( graph, partials, path) . unwrap ( ) ;
259285 }
260- last_idx = idx;
286+
287+ // build cyclic path
261288 prefix_path
262289 . resolve_to ( graph, partials, cyclic_path. start_node )
263290 . unwrap ( ) ;
@@ -271,7 +298,5 @@ impl PartialPathAppendingCycleDetector {
271298 return Err ( ( ) ) ;
272299 }
273300 }
274-
275- Ok ( ( ) )
276301 }
277302}
0 commit comments