Skip to content

Commit eabb699

Browse files
authored
perf: walk lazy-indexed directories in parallel (#115)
### Changes are visible to end-users: no ### Test plan - Covered by existing test cases - Manual testing; running with `--index=lazy` on subdirs with many deps that get lazy-walked
1 parent b863408 commit eabb699

File tree

2 files changed

+44
-17
lines changed

2 files changed

+44
-17
lines changed

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ bazel_dep(name = "gazelle", version = "0.45.0")
99
# Go modules
1010
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
1111
go_deps.from_file(go_mod = "//common:go.mod")
12-
use_repo(go_deps, "com_github_bazelbuild_buildtools", "com_github_bmatcuk_doublestar_v4", "com_github_emirpasic_gods", "com_github_onsi_gomega", "com_github_smacker_go_tree_sitter", "in_gopkg_op_go_logging_v1")
12+
use_repo(go_deps, "com_github_bazelbuild_buildtools", "com_github_bmatcuk_doublestar_v4", "com_github_emirpasic_gods", "com_github_onsi_gomega", "com_github_smacker_go_tree_sitter", "in_gopkg_op_go_logging_v1", "org_golang_x_sync")
1313

1414
# tree-sitter languages
1515
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

common/walk.go

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"log"
55
"slices"
66
"strings"
7+
"sync"
78

89
"github.com/bazelbuild/bazel-gazelle/walk"
910
)
@@ -43,31 +44,57 @@ func GetSourceRegularFiles(rel string) ([]string, error) {
4344
if err != nil {
4445
return nil, err
4546
}
47+
if len(d.Subdirs) == 0 {
48+
return d.RegularFiles, nil
49+
}
50+
51+
// Use channels to collect results from parallel goroutines.
52+
// Gazelle may populate the initial directory cache of the initially walked directories
53+
// but incremental runs will not have walked lazy-indexed subdirectories.
54+
resultChan := make(chan string, len(d.Subdirs))
55+
wg := &sync.WaitGroup{}
4656

4757
if rel != "" {
4858
rel = rel + "/"
4959
}
50-
return getSourceRegularSubFiles(rel, "", d, d.RegularFiles[:])
60+
collectSourceRegularSubFiles(wg, rel, "", d, resultChan)
61+
62+
// Close the channel when all goroutines are done
63+
go func() {
64+
wg.Wait()
65+
close(resultChan)
66+
}()
67+
68+
// Collect results from all goroutines
69+
files := d.RegularFiles[:]
70+
for res := range resultChan {
71+
files = append(files, res)
72+
}
73+
slices.Sort(files)
74+
return files, nil
5175
}
5276

53-
func getSourceRegularSubFiles(base, rel string, d walk.DirInfo, files []string) ([]string, error) {
77+
func collectSourceRegularSubFiles(wg *sync.WaitGroup, base, rel string, d walk.DirInfo, resultChan chan<- string) {
5478
for _, sdRel := range d.Subdirs {
55-
if rel != "" {
56-
sdRel = rel + "/" + sdRel
57-
}
79+
wg.Add(1)
80+
go func(sdRel string) {
81+
defer wg.Done()
5882

59-
sdInfo, _ := walk.GetDirInfo(base + sdRel)
60-
61-
// Recurse into subdirectories that do not have a BUILD file just like a
62-
// bazel BUILD glob() would.
63-
if sdInfo.File == nil {
64-
for _, f := range sdInfo.RegularFiles {
65-
files = append(files, sdRel+"/"+f)
83+
if rel != "" {
84+
sdRel = rel + "/" + sdRel
6685
}
6786

68-
files, _ = getSourceRegularSubFiles(base, sdRel, sdInfo, files)
69-
}
70-
}
87+
sdInfo, _ := walk.GetDirInfo(base + sdRel)
7188

72-
return files, nil
89+
// Recurse into subdirectories that do not have a BUILD file just like a
90+
// bazel BUILD glob() would.
91+
if sdInfo.File == nil {
92+
for _, f := range sdInfo.RegularFiles {
93+
resultChan <- sdRel + "/" + f
94+
}
95+
96+
collectSourceRegularSubFiles(wg, base, sdRel, sdInfo, resultChan)
97+
}
98+
}(sdRel)
99+
}
73100
}

0 commit comments

Comments
 (0)