@@ -152,39 +152,41 @@ export default {
152
152
* Populates `cyclic` with cyclic segments.
153
153
*/
154
154
155
- function countPathsFromStart ( segment ) {
155
+ function countPathsFromStart ( segment , pathHistory ) {
156
156
const { cache} = countPathsFromStart ;
157
157
let paths = cache . get ( segment . id ) ;
158
-
159
- // If `paths` is null then we've found a cycle! Add it to `cyclic` and
160
- // any other segments which are a part of this cycle.
161
- if ( paths === null ) {
162
- if ( cyclic . has ( segment . id ) ) {
163
- return 0 ;
164
- } else {
165
- cyclic . add ( segment . id ) ;
166
- for ( const prevSegment of segment . prevSegments ) {
167
- countPathsFromStart ( prevSegment ) ;
168
- }
169
- return 0 ;
158
+ const pathList = new Set ( pathHistory ) ;
159
+
160
+ // If `pathList` includes the current segment then we've found a cycle!
161
+ // We need to fill `cyclic` with all segments inside cycle
162
+ if ( pathList . has ( segment . id ) ) {
163
+ const pathArray = [ ...pathList ] ;
164
+ const cyclicSegments = pathArray . slice (
165
+ pathArray . indexOf ( segment . id ) + 1 ,
166
+ ) ;
167
+ for ( const cyclicSegment of cyclicSegments ) {
168
+ cyclic . add ( cyclicSegment ) ;
170
169
}
170
+
171
+ return 0 ;
171
172
}
172
173
174
+ // add the current segment to pathList
175
+ pathList . add ( segment . id ) ;
176
+
173
177
// We have a cached `paths`. Return it.
174
178
if ( paths !== undefined ) {
175
179
return paths ;
176
180
}
177
181
178
- // Compute `paths` and cache it. Guarding against cycles.
179
- cache . set ( segment . id , null ) ;
180
182
if ( codePath . thrownSegments . includes ( segment ) ) {
181
183
paths = 0 ;
182
184
} else if ( segment . prevSegments . length === 0 ) {
183
185
paths = 1 ;
184
186
} else {
185
187
paths = 0 ;
186
188
for ( const prevSegment of segment . prevSegments ) {
187
- paths += countPathsFromStart ( prevSegment ) ;
189
+ paths += countPathsFromStart ( prevSegment , pathList ) ;
188
190
}
189
191
}
190
192
@@ -221,43 +223,45 @@ export default {
221
223
* Populates `cyclic` with cyclic segments.
222
224
*/
223
225
224
- function countPathsToEnd ( segment ) {
226
+ function countPathsToEnd ( segment , pathHistory ) {
225
227
const { cache} = countPathsToEnd ;
226
228
let paths = cache . get ( segment . id ) ;
227
-
228
- // If `paths` is null then we've found a cycle! Add it to `cyclic` and
229
- // any other segments which are a part of this cycle.
230
- if ( paths === null ) {
231
- if ( cyclic . has ( segment . id ) ) {
232
- return 0 ;
233
- } else {
234
- cyclic . add ( segment . id ) ;
235
- for ( const nextSegment of segment . nextSegments ) {
236
- countPathsToEnd ( nextSegment ) ;
237
- }
238
- return 0 ;
229
+ let pathList = new Set ( pathHistory ) ;
230
+
231
+ // If `pathList` includes the current segment then we've found a cycle!
232
+ // We need to fill `cyclic` with all segments inside cycle
233
+ if ( pathList . has ( segment . id ) ) {
234
+ const pathArray = Array . from ( pathList ) ;
235
+ const cyclicSegments = pathArray . slice (
236
+ pathArray . indexOf ( segment . id ) + 1 ,
237
+ ) ;
238
+ for ( const cyclicSegment of cyclicSegments ) {
239
+ cyclic . add ( cyclicSegment ) ;
239
240
}
241
+
242
+ return 0 ;
240
243
}
241
244
245
+ // add the current segment to pathList
246
+ pathList . add ( segment . id ) ;
247
+
242
248
// We have a cached `paths`. Return it.
243
249
if ( paths !== undefined ) {
244
250
return paths ;
245
251
}
246
252
247
- // Compute `paths` and cache it. Guarding against cycles.
248
- cache . set ( segment . id , null ) ;
249
253
if ( codePath . thrownSegments . includes ( segment ) ) {
250
254
paths = 0 ;
251
255
} else if ( segment . nextSegments . length === 0 ) {
252
256
paths = 1 ;
253
257
} else {
254
258
paths = 0 ;
255
259
for ( const nextSegment of segment . nextSegments ) {
256
- paths += countPathsToEnd ( nextSegment ) ;
260
+ paths += countPathsToEnd ( nextSegment , pathList ) ;
257
261
}
258
262
}
259
- cache . set ( segment . id , paths ) ;
260
263
264
+ cache . set ( segment . id , paths ) ;
261
265
return paths ;
262
266
}
263
267
0 commit comments