Skip to content

Commit db05956

Browse files
authored
Merge pull request #39 from tscircuit/selectRoutesToRip
feature: selectRoutesToRip use this as a partial ripping; you select which route to you want to rip
1 parent 994f322 commit db05956

File tree

1 file changed

+57
-26
lines changed

1 file changed

+57
-26
lines changed

lib/HyperGraphSolver.ts

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,59 @@ export class HyperGraphSolver<
170170
return candidates
171171
}
172172

173+
/**
174+
* OPTIONALLY OVERRIDE THIS
175+
*
176+
* Compute the full set of solved routes that must be ripped to accept
177+
* `newlySolvedRoute`. By default this returns all conflicting routes
178+
* (always-rip behavior)
179+
*
180+
* Override this to implement partial ripping, where only a subset of
181+
* conflicting routes are removed.
182+
*/
183+
computeRoutesToRip(newlySolvedRoute: SolvedRoute): Set<SolvedRoute> {
184+
const crossingRoutesToRip = this.computeCrossingRoutes(newlySolvedRoute)
185+
const portReuseRoutesToRip = this.computePortOverlapRoutes(newlySolvedRoute)
186+
return new Set<SolvedRoute>([
187+
...crossingRoutesToRip,
188+
...portReuseRoutesToRip,
189+
])
190+
}
191+
192+
/**
193+
* Returns solved routes that overlap ports with the newly solved route.
194+
* Use this in computeRoutesToRip overrides to include port reuse rips.
195+
*/
196+
computePortOverlapRoutes(newlySolvedRoute: SolvedRoute): Set<SolvedRoute> {
197+
const portReuseRoutesToRip: Set<SolvedRoute> = new Set()
198+
for (const candidate of newlySolvedRoute.path) {
199+
if (
200+
candidate.port.assignment &&
201+
candidate.port.assignment.connection.mutuallyConnectedNetworkId !==
202+
newlySolvedRoute.connection.mutuallyConnectedNetworkId
203+
) {
204+
portReuseRoutesToRip.add(candidate.port.assignment.solvedRoute)
205+
}
206+
}
207+
return portReuseRoutesToRip
208+
}
209+
210+
computeCrossingRoutes(newlySolvedRoute: SolvedRoute): Set<SolvedRoute> {
211+
const crossingRoutesToRip: Set<SolvedRoute> = new Set()
212+
for (const candidate of newlySolvedRoute.path) {
213+
if (!candidate.lastPort || !candidate.lastRegion) continue
214+
const ripsRequired = this.getRipsRequiredForPortUsage(
215+
candidate.lastRegion as RegionType,
216+
candidate.lastPort as RegionPortType,
217+
candidate.port as RegionPortType,
218+
)
219+
for (const assignment of ripsRequired) {
220+
crossingRoutesToRip.add(assignment.solvedRoute)
221+
}
222+
}
223+
return crossingRoutesToRip
224+
}
225+
173226
getNextCandidates(currentCandidate: CandidateType): CandidateType[] {
174227
const currentRegion = currentCandidate.nextRegion!
175228
const currentPort = currentCandidate.port
@@ -234,38 +287,16 @@ export class HyperGraphSolver<
234287
cursorCandidate = cursorCandidate.parent as CandidateType | undefined
235288
}
236289

237-
// Rip any routes that are connected to the solved route (port reuse) and requeue
238-
const routesToRip: Set<SolvedRoute> = new Set()
239290
if (anyRipsRequired) {
240291
solvedRoute.requiredRip = true
241-
for (const candidate of solvedRoute.path) {
242-
if (
243-
candidate.port.assignment &&
244-
candidate.port.assignment.connection.mutuallyConnectedNetworkId !==
245-
this.currentConnection!.mutuallyConnectedNetworkId
246-
) {
247-
routesToRip.add(candidate.port.assignment.solvedRoute)
248-
}
249-
}
250292
}
251293

252-
// Check for rips required due to port usage (crossing assignments)
253-
for (const candidate of solvedRoute.path) {
254-
if (!candidate.lastPort || !candidate.lastRegion) continue
255-
const ripsRequired = this.getRipsRequiredForPortUsage(
256-
candidate.lastRegion as RegionType,
257-
candidate.lastPort as RegionPortType,
258-
candidate.port as RegionPortType,
259-
)
260-
for (const assignment of ripsRequired) {
261-
routesToRip.add(assignment.solvedRoute)
262-
}
263-
}
294+
const allRoutesToRip = this.computeRoutesToRip(solvedRoute)
264295

265-
// Perform the ripping
266-
if (routesToRip.size > 0) {
296+
// Rip conflicting routes before committing assignments.
297+
if (allRoutesToRip.size > 0) {
267298
solvedRoute.requiredRip = true
268-
for (const route of routesToRip) {
299+
for (const route of allRoutesToRip) {
269300
this.ripSolvedRoute(route)
270301
}
271302
}

0 commit comments

Comments
 (0)