# UNDF: UNDF-2026-000000104 --- a/internal/chart/v3/util/dependencies.go +++ b/internal/chart/v3/util/dependencies.go @@ -144,18 +144,22 @@ func processDependencyEnabled(c *chart.Chart, v map[string]any, path string) err } var chartDependencies []*chart.Chart - // If any dependency is not a part of Chart.yaml - // then this should be added to chartDependencies. - // However, if the dependency is already specified in Chart.yaml - // we should not add it, as it would be processed from Chart.yaml anyway. - -Loop: - for _, existing := range c.Dependencies() { - for _, req := range c.Metadata.Dependencies { - if existing.Name() == req.Name && IsCompatibleRange(req.Version, existing.Metadata.Version) { - continue Loop - } + // Index metadata deps by name for O(1) lookup — avoids O(existing × metaDeps). + metaDepByName := make(map[string]*chart.Dependency, len(c.Metadata.Dependencies)) + for _, req := range c.Metadata.Dependencies { + if req != nil { + metaDepByName[req.Name] = req } - chartDependencies = append(chartDependencies, existing) + } + // Keep loaded charts that are NOT described in Chart.yaml (extra deps). + for _, existing := range c.Dependencies() { + if req, found := metaDepByName[existing.Name()]; found { + if IsCompatibleRange(req.Version, existing.Metadata.Version) { + continue // covered by Chart.yaml processing below + } + } + chartDependencies = append(chartDependencies, existing) } + // Index loaded deps by name for O(1) alias resolution — avoids O(metaDeps × charts). + chartsByName := make(map[string]*chart.Chart, len(c.Dependencies())) + for _, ch := range c.Dependencies() { + if ch != nil { + chartsByName[ch.Name()] = ch + } + } for _, req := range c.Metadata.Dependencies { if req == nil { continue } - if chartDependency := getAliasDependency(c.Dependencies(), req); chartDependency != nil { - chartDependencies = append(chartDependencies, chartDependency) + // getAliasDependency still used for version-range check and alias copy; + // pre-built map avoids the O(charts) linear scan inside it. + if ch, ok := chartsByName[req.Name]; ok { + if chartDependency := getAliasDependency([]*chart.Chart{ch}, req); chartDependency != nil { + chartDependencies = append(chartDependencies, chartDependency) + } } if req.Alias != "" { req.Name = req.Alias