]> Cypherpunks.ru repositories - goredo.git/blobdiff - ifchange.go
Refactor target paths, less CPU, less memory, more clarity
[goredo.git] / ifchange.go
index 77d6d93dccc01459b3950d18c7819d22f5729519..9f7f4b572d583c1a5fbdf216f7788e280a7e8431 100644 (file)
@@ -18,90 +18,80 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 package main
 
 import (
-       "path"
        "strings"
 )
 
 func collectDeps(
-       cwd, tgtOrig string,
+       tgt *Tgt,
        level int,
-       deps map[string]map[string]struct{},
+       deps map[string]map[string]*Tgt,
        includeSrc bool,
        seen map[string]struct{},
-) []string {
-       cwd, tgt := cwdAndTgt(path.Join(cwd, tgtOrig))
-       tgtFull := path.Join(cwd, tgt)
-       if _, ok := seen[tgtFull]; ok {
+) []*Tgt {
+       if _, ok := seen[tgt.a]; ok {
                return nil
        }
-       depPath := path.Join(cwd, RedoDir, tgt+DepSuffix)
-       depInfo, err := depRead(depPath)
+       depInfo, err := depRead(tgt)
        if err != nil {
                return nil
        }
-       // DepInfoCache[depPath] = depInfo
-       seen[tgtFull] = struct{}{}
-       var alwayses []string
+       seen[tgt.a] = struct{}{}
+       var alwayses []*Tgt
        returnReady := false
-       tgtRel := cwdMustRel(cwd, tgt)
        if depInfo.always {
                if depInfo.build == BuildUUID {
                        tracef(
                                CDebug, "ood: %s%s always, but already build",
-                               strings.Repeat(". ", level), tgtOrig,
+                               strings.Repeat(". ", level), tgt,
                        )
                        returnReady = true
                } else {
-                       tracef(CDebug, "ood: %s%s always", strings.Repeat(". ", level), tgtOrig)
-                       alwayses = append(alwayses, tgtRel)
+                       tracef(CDebug, "ood: %s%s always", strings.Repeat(". ", level), tgt)
+                       alwayses = append(alwayses, tgt)
                        returnReady = true
                }
        }
        for _, dep := range depInfo.ifchanges {
-               if dep.tgt == tgt {
+               if dep.tgt.a == tgt.a {
                        continue
                }
-               if !includeSrc && isSrc(cwd, dep.tgt) {
+               if !includeSrc && isSrc(dep.tgt) {
                        continue
                }
                if !returnReady {
-                       depRel := cwdMustRel(cwd, dep.tgt)
-                       if m, ok := deps[depRel]; ok {
-                               m[tgtRel] = struct{}{}
+                       if m, ok := deps[dep.tgt.a]; ok {
+                               m[tgt.a] = tgt
                        } else {
-                               m = map[string]struct{}{}
-                               m[tgtRel] = struct{}{}
-                               deps[depRel] = m
+                               deps[dep.tgt.a] = map[string]*Tgt{tgt.a: tgt}
                        }
                        alwayses = append(alwayses,
-                               collectDeps(cwd, dep.tgt, level+1, deps, includeSrc, seen)...)
+                               collectDeps(dep.tgt, level+1, deps, includeSrc, seen)...)
                }
        }
        return alwayses
 }
 
-func buildDependants(tgts []string) map[string]struct{} {
+func buildDependants(tgts []*Tgt) map[string]*Tgt {
        defer Jobs.Wait()
        tracef(CDebug, "collecting deps")
-       seen := map[string]struct{}{}
-       deps := map[string]map[string]struct{}{}
-       collectDepsSeen := make(map[string]struct{})
-       for _, tgtInitial := range tgts {
-               for _, tgt := range collectDeps(Cwd, tgtInitial, 0, deps, false, collectDepsSeen) {
-                       if tgt != tgtInitial {
-                               seen[tgt] = struct{}{}
+       seen := make(map[string]*Tgt)
+       deps := make(map[string]map[string]*Tgt)
+       {
+               collectDepsSeen := make(map[string]struct{})
+               for _, tgtInitial := range tgts {
+                       for _, tgt := range collectDeps(tgtInitial, 0, deps, false, collectDepsSeen) {
+                               if tgt.a != tgtInitial.a {
+                                       seen[tgt.a] = tgt
+                               }
                        }
                }
        }
        if len(seen) == 0 {
                return seen
        }
-       collectDepsSeen = nil
 
        levelOrig := Level
-       defer func() {
-               Level = levelOrig
-       }()
+       defer func() { Level = levelOrig }()
        Level = 1
        tracef(CDebug, "building %d alwayses: %v", len(seen), seen)
        errs := make(chan error, len(seen))
@@ -113,7 +103,7 @@ func buildDependants(tgts []string) map[string]struct{} {
                }
                close(okChecker)
        }()
-       for tgt := range seen {
+       for _, tgt := range seen {
                if err := runScript(tgt, errs, false, false); err != nil {
                        tracef(CErr, "always run error: %s, skipping dependants", err)
                        Jobs.Wait()
@@ -129,17 +119,17 @@ func buildDependants(tgts []string) map[string]struct{} {
                return nil
        }
 
-       queueSrc := make([]string, 0, len(seen))
-       for tgt := range seen {
+       queueSrc := make([]*Tgt, 0, len(seen))
+       for _, tgt := range seen {
                queueSrc = append(queueSrc, tgt)
        }
 
 RebuildDeps:
        tracef(CDebug, "checking %d dependant targets: %v", len(queueSrc), queueSrc)
-       queue := map[string]struct{}{}
+       queue := make(map[string]*Tgt)
        for _, tgt := range queueSrc {
-               for dep := range deps[tgt] {
-                       queue[dep] = struct{}{}
+               for _, dep := range deps[tgt.a] {
+                       queue[dep.a] = dep
                }
        }
 
@@ -147,15 +137,15 @@ RebuildDeps:
        errs = make(chan error, len(queue))
        okChecker = make(chan struct{})
        jobs := 0
-       queueSrc = []string{}
+       queueSrc = make([]*Tgt, 0)
        go func() {
                for err := range errs {
                        ok = isOkRun(err) && ok
                }
                close(okChecker)
        }()
-       for tgt := range queue {
-               ood, err := isOODWithTrace(Cwd, tgt, 0, seen)
+       for _, tgt := range queue {
+               ood, err := isOODWithTrace(tgt, 0, seen)
                if err != nil {
                        tracef(CErr, "dependant error: %s, skipping dependants", err)
                        return nil
@@ -168,7 +158,7 @@ RebuildDeps:
                        return nil
                }
                queueSrc = append(queueSrc, tgt)
-               seen[tgt] = struct{}{}
+               seen[tgt.a] = tgt
                jobs++
        }
        Jobs.Wait()
@@ -185,17 +175,18 @@ RebuildDeps:
        goto RebuildDeps
 }
 
-func ifchange(tgts []string, forced, traced bool) (bool, error) {
-       // only unique elements
-       m := make(map[string]struct{})
-       for _, t := range tgts {
-               m[t] = struct{}{}
-       }
-       tgts = tgts[:0]
-       for t := range m {
-               tgts = append(tgts, t)
+func ifchange(tgts []*Tgt, forced, traced bool) (bool, error) {
+       {
+               // only unique elements
+               m := make(map[string]*Tgt)
+               for _, t := range tgts {
+                       m[t.a] = t
+               }
+               tgts = tgts[:0]
+               for _, t := range m {
+                       tgts = append(tgts, t)
+               }
        }
-       m = nil
 
        jsInit()
        if !IsTopRedo {
@@ -220,13 +211,13 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) {
                close(okChecker)
        }()
        for _, tgt := range tgts {
-               if _, ok := seen[tgt]; ok {
+               if _, ok := seen[tgt.a]; ok {
                        tracef(CDebug, "%s was already build as a dependant", tgt)
                        continue
                }
                ood = true
                if !forced {
-                       ood, err = isOODWithTrace(Cwd, tgt, 0, seen)
+                       ood, err = isOODWithTrace(tgt, 0, seen)
                        if err != nil {
                                Jobs.Wait()
                                close(errs)
@@ -236,7 +227,7 @@ func ifchange(tgts []string, forced, traced bool) (bool, error) {
                if !ood {
                        continue
                }
-               if isSrc(Cwd, tgt) {
+               if isSrc(tgt) {
                        tracef(CDebug, "%s is source, not redoing", tgt)
                        continue
                }