From: Sergey Matveev Date: Sat, 30 Sep 2023 09:58:25 +0000 (+0300) Subject: Optimise redo-sources X-Git-Tag: v2.0.0~32 X-Git-Url: http://www.git.cypherpunks.ru/?p=goredo.git;a=commitdiff_plain;h=e935c1db3ae2ff6d920ff37802774ba2e85629f0 Optimise redo-sources --- diff --git a/main.go b/main.go index 025ecbe..c05d3c7 100644 --- a/main.go +++ b/main.go @@ -499,11 +499,23 @@ CmdSwitch: } } sort.Strings(tgts) - var srcs []string - srcs, err = sourcesWalker(tgts) - err = ErrLine(err) - sort.Strings(srcs) - for _, src := range srcs { + seen := make(map[string]struct{}) + seenDeps := make(map[string]struct{}) + srcs := make(map[string]struct{}) + err = ErrLine(sourcesWalker(tgts, seen, seenDeps, srcs)) + seen = nil + seenDeps = nil + if err != nil { + break + } + seenDeps = nil + res := make([]string, 0, len(srcs)) + for p := range srcs { + res = append(res, p) + } + srcs = nil + sort.Strings(res) + for _, src := range res { fmt.Println(src) } case CmdNameRedoDepFix: diff --git a/sources.go b/sources.go index d53e0e3..3f375a6 100644 --- a/sources.go +++ b/sources.go @@ -18,47 +18,54 @@ along with this program. If not, see . package main import ( - "log" "os" "path" ) -func sourcesWalker(tgts []string) ([]string, error) { - seen := make(map[string]struct{}, 1<<10) +func sourcesWalker( + tgts []string, + seen map[string]struct{}, + seenDeps map[string]struct{}, + srcs map[string]struct{}, +) error { for _, tgt := range tgts { tgtAbsPath := mustAbs(path.Join(Cwd, tgt)) cwd, f := path.Split(path.Join(Cwd, tgt)) - fdDep, err := os.Open(path.Join(cwd, RedoDir, f+DepSuffix)) + depPath := path.Join(cwd, RedoDir, f+DepSuffix) + if _, ok := seenDeps[depPath]; ok { + continue + } + seenDeps[depPath] = struct{}{} + fdDep, err := os.Open(depPath) if err != nil { if errors.Is(err, fs.ErrNotExist) { continue } - return nil, ErrLine(err) + return ErrLine(err) } depInfo, err := depRead(fdDep) fdDep.Close() if err != nil { - return nil, ErrLine(err) + return ErrLine(err) } for _, m := range depInfo.ifchanges { depTgt := m["Target"] depTgtAbsPath := mustAbs(path.Join(cwd, depTgt)) + if _, ok := seen[depTgtAbsPath]; ok { + continue + } + seen[depTgtAbsPath] = struct{}{} if isSrc(cwd, depTgt) { - seen[cwdMustRel(depTgtAbsPath)] = struct{}{} + srcs[cwdMustRel(depTgtAbsPath)] = struct{}{} } else if depTgtAbsPath != tgtAbsPath { - subSrcs, err := sourcesWalker([]string{cwdMustRel(depTgtAbsPath)}) - if err != nil { - log.Fatal(err) - } - for _, p := range subSrcs { - seen[p] = struct{}{} + if err := sourcesWalker( + []string{cwdMustRel(depTgtAbsPath)}, + seen, seenDeps, srcs, + ); err != nil { + return err } } } } - srcs := make([]string, 0, len(seen)) - for p := range seen { - srcs = append(srcs, p) - } - return srcs, nil + return nil }