diff --git a/ext/go.mod b/ext/go.mod index ffa47518..c33ce02d 100644 --- a/ext/go.mod +++ b/ext/go.mod @@ -26,7 +26,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect - github.com/google/pprof v0.0.0-20241023014458-598669927662 // indirect + github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect diff --git a/ext/go.sum b/ext/go.sum index 7c6831a6..73250205 100644 --- a/ext/go.sum +++ b/ext/go.sum @@ -31,8 +31,8 @@ github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20241023014458-598669927662 h1:SKMkD83p7FwUqKmBsPdLHF5dNyxq3jOWwu9w9UyH5vA= -github.com/google/pprof v0.0.0-20241023014458-598669927662/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs= +github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= diff --git a/pkg/chart/table.go b/pkg/chart/table.go index 8d56d00e..0cc613d9 100644 --- a/pkg/chart/table.go +++ b/pkg/chart/table.go @@ -147,9 +147,9 @@ func (t *Table) free(id uuid.UUID) (*Chart, error) { func (t *Table) load(chrt *Chart) error { linked := t.linked(chrt) - for _, sb := range linked { - if t.active(sb) { - if err := t.linkHooks.Link(sb); err != nil { + for _, chrt := range linked { + if t.active(chrt) { + if err := t.linkHooks.Link(chrt); err != nil { return err } } @@ -160,9 +160,9 @@ func (t *Table) load(chrt *Chart) error { func (t *Table) unload(chrt *Chart) error { linked := t.linked(chrt) for i := len(linked) - 1; i >= 0; i-- { - sb := linked[i] - if t.active(sb) { - if err := t.unlinkHooks.Unlink(sb); err != nil { + chrt := linked[i] + if t.active(chrt) { + if err := t.unlinkHooks.Unlink(chrt); err != nil { return err } } @@ -213,50 +213,48 @@ func (t *Table) unlinks(chrt *Chart) { func (t *Table) linked(chrt *Chart) []*Chart { var linked []*Chart - paths := []*Chart{chrt} - for len(paths) > 0 { - sb := paths[len(paths)-1] - ok := true - for _, id := range t.references[sb.GetID()] { - next := t.charts[id] - ok = slices.Contains(paths, next) || slices.Contains(linked, next) - if !ok { - paths = append(paths, next) - break - } + stack := []*Chart{chrt} + for len(stack) > 0 { + curr := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if slices.Contains(linked, curr) { + continue } - if ok { - paths = paths[0 : len(paths)-1] - linked = append(linked, sb) + linked = append(linked, curr) + + for _, id := range t.references[curr.GetID()] { + if next, ok := t.charts[id]; ok { + stack = append(stack, next) + } } } - slices.Reverse(linked) return linked } func (t *Table) active(chrt *Chart) bool { var linked []*Chart - paths := []*Chart{chrt} - for len(paths) > 0 { - chrt := paths[len(paths)-1] + stack := []*Chart{chrt} + for len(stack) > 0 { + curr := stack[len(stack)-1] ok := true - for _, sp := range chrt.Specs { - id := t.lookup(chrt.GetNamespace(), sp.GetKind()) + for _, sp := range curr.Specs { + id := t.lookup(curr.GetNamespace(), sp.GetKind()) next := t.charts[id] - if next == nil || slices.Contains(paths, next) { + if next == nil || slices.Contains(stack, next) { return false } ok = slices.Contains(linked, next) if !ok { - paths = append(paths, next) + stack = append(stack, next) break } } if ok { - paths = paths[0 : len(paths)-1] - linked = append(linked, chrt) + stack = stack[0 : len(stack)-1] + linked = append(linked, curr) } } return true diff --git a/pkg/symbol/table.go b/pkg/symbol/table.go index 74c4fe71..d4f0710c 100644 --- a/pkg/symbol/table.go +++ b/pkg/symbol/table.go @@ -21,7 +21,7 @@ type TableOption struct { type Table struct { symbols map[uuid.UUID]*Symbol namespaces map[string]map[string]uuid.UUID - refences map[uuid.UUID]map[string][]spec.Port + references map[uuid.UUID]map[string][]spec.Port loadHooks LoadHooks unloadHooks UnloadHooks mu sync.RWMutex @@ -39,7 +39,7 @@ func NewTable(opts ...TableOption) *Table { return &Table{ symbols: make(map[uuid.UUID]*Symbol), namespaces: make(map[string]map[string]uuid.UUID), - refences: make(map[uuid.UUID]map[string][]spec.Port), + references: make(map[uuid.UUID]map[string][]spec.Port), loadHooks: loadHooks, unloadHooks: unloadHooks, } @@ -191,10 +191,10 @@ func (t *Table) links(sb *Symbol) { out.Link(in) } - refences := t.refences[ref.ID()] + refences := t.references[ref.ID()] if refences == nil { refences = make(map[string][]spec.Port) - t.refences[ref.ID()] = refences + t.references[ref.ID()] = refences } refences[port.Port] = append(refences[port.Port], spec.Port{ @@ -222,10 +222,10 @@ func (t *Table) links(sb *Symbol) { out.Link(in) } - refences := t.refences[sb.ID()] + refences := t.references[sb.ID()] if refences == nil { refences = make(map[string][]spec.Port) - t.refences[sb.ID()] = refences + t.references[sb.ID()] = refences } refences[port.Port] = append(refences[port.Port], spec.Port{ @@ -252,10 +252,10 @@ func (t *Table) unlinks(sb *Symbol) { continue } - refences := t.refences[ref.ID()] + refences := t.references[ref.ID()] if refences == nil { refences = make(map[string][]spec.Port) - t.refences[ref.ID()] = refences + t.references[ref.ID()] = refences } var ports []spec.Port @@ -273,62 +273,63 @@ func (t *Table) unlinks(sb *Symbol) { } } - delete(t.refences, sb.ID()) + delete(t.references, sb.ID()) } func (t *Table) linked(sb *Symbol) []*Symbol { var linked []*Symbol - paths := []*Symbol{sb} - for len(paths) > 0 { - sb := paths[len(paths)-1] - ok := true - for _, ports := range t.refences[sb.ID()] { + stack := []*Symbol{sb} + + for len(stack) > 0 { + curr := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if slices.Contains(linked, curr) { + continue + } + linked = append(linked, curr) + + for _, ports := range t.references[curr.ID()] { for _, port := range ports { - next := t.symbols[port.ID] - ok = slices.Contains(paths, next) || slices.Contains(linked, next) - if !ok { - paths = append(paths, next) - break + id := port.ID + if id == uuid.Nil { + id = t.lookup(curr.Namespace(), port.Name) + } + + if next, ok := t.symbols[id]; ok { + stack = append(stack, next) } - } - if !ok { - break } } - if ok { - paths = paths[0 : len(paths)-1] - linked = append(linked, sb) - } } - slices.Reverse(linked) return linked } func (t *Table) active(sb *Symbol) bool { - nexts := []*Symbol{sb} - visits := map[*Symbol]struct{}{} - for len(nexts) > 0 { - sb := nexts[0] - nexts = nexts[1:] + stack := []*Symbol{sb} + visited := map[*Symbol]struct{}{} + + for len(stack) > 0 { + curr := stack[len(stack)-1] + stack = stack[:len(stack)-1] - if _, visit := visits[sb]; visit { + if _, ok := visited[curr]; ok { continue } - visits[sb] = struct{}{} + visited[curr] = struct{}{} - for _, ports := range sb.Ports() { + for _, ports := range curr.Ports() { for _, port := range ports { id := port.ID if id == uuid.Nil { - id = t.lookup(sb.Namespace(), port.Name) + id = t.lookup(curr.Namespace(), port.Name) } - ref, ok := t.symbols[id] - if !ok || ref.Namespace() != sb.Namespace() { + next, ok := t.symbols[id] + if !ok || next.Namespace() != curr.Namespace() { return false } - - nexts = append(nexts, ref) + stack = append(stack, next) } } }