Files
Jo 6e6d39d595 perf(deps): improve dependency resolution performance (#2890)
* improve topo performance

* fix: Resolve data race in dep_graph_test and clean up local mods

* cleanup

* feat(dep): add split functionality

* cleanup mem allocs
2026-06-24 00:20:04 +02:00

84 lines
1.4 KiB
Go

package dep
import "strings"
// splitDep splits a dependency string into name, operator and version.
func splitDep(dep string) (pkg, mod, ver string) {
var (
f0s, f0e = -1, -1 // first field bounds
f1s, f1e = -1, -1 // second field bounds
fields int
modBuf [8]byte // operator bytes in order; real deps use at most 2
modLen int
)
for i := 0; i < len(dep); {
if c := dep[i]; c == '<' || c == '>' || c == '=' {
if modLen < len(modBuf) {
modBuf[modLen] = c
}
modLen++
i++
continue
}
start := i
for i < len(dep) && dep[i] != '<' && dep[i] != '>' && dep[i] != '=' {
i++
}
fields++
switch fields {
case 1:
f0s, f0e = start, i
case 2:
f1s, f1e = start, i
}
}
switch fields {
case 0:
return "", "", ""
case 1:
return dep[f0s:f0e], "", ""
}
n := min(modLen, len(modBuf))
return dep[f0s:f0e], internMod(modBuf[:n], modLen, dep), dep[f1s:f1e]
}
// internMod returns the operator string without allocating for common cases.
func internMod(b []byte, modLen int, dep string) string {
if modLen > len(b) {
var sb strings.Builder
for i := 0; i < len(dep); i++ {
if c := dep[i]; c == '<' || c == '>' || c == '=' {
sb.WriteByte(c)
}
}
return sb.String()
}
switch string(b) {
case "=":
return "="
case "<":
return "<"
case ">":
return ">"
case "<=":
return "<="
case ">=":
return ">="
case "=<":
return "=<"
case "=>":
return "=>"
default:
return string(b)
}
}