Skip to content

Commit a339e37

Browse files
adonovangopherbot
authored andcommitted
gopls/internal/util/persistent: {Map,Set}: use iter.Seq2
This CL updates the tree data structures to use go1.23-style iterators. package persistent func (*Map[K, V]) Keys() iter.Seq[K] func (*Map[K, V]) All() iter.Seq2[K, V] func (*Set[K]) All() iter.Seq[K] Change-Id: I4b8917fa35c38e055e42e10cefea7997fe7b35f3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/640035 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Alan Donovan <[email protected]>
1 parent a2408f8 commit a339e37

File tree

9 files changed

+69
-63
lines changed

9 files changed

+69
-63
lines changed

gopls/internal/cache/filemap.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package cache
66

77
import (
8+
"iter"
89
"path/filepath"
910

1011
"golang.org/x/tools/gopls/internal/file"
@@ -77,9 +78,9 @@ func (m *fileMap) get(key protocol.DocumentURI) (file.Handle, bool) {
7778
return m.files.Get(key)
7879
}
7980

80-
// foreach calls f for each (uri, fh) in the map.
81-
func (m *fileMap) foreach(f func(uri protocol.DocumentURI, fh file.Handle)) {
82-
m.files.Range(f)
81+
// all returns the sequence of (uri, fh) entries in the map.
82+
func (m *fileMap) all() iter.Seq2[protocol.DocumentURI, file.Handle] {
83+
return m.files.All()
8384
}
8485

8586
// set stores the given file handle for key, updating overlays and directories
@@ -130,9 +131,9 @@ func (m *fileMap) delete(key protocol.DocumentURI) {
130131
// getOverlays returns a new unordered array of overlay files.
131132
func (m *fileMap) getOverlays() []*overlay {
132133
var overlays []*overlay
133-
m.overlays.Range(func(_ protocol.DocumentURI, o *overlay) {
134+
for _, o := range m.overlays.All() {
134135
overlays = append(overlays, o)
135-
})
136+
}
136137
return overlays
137138
}
138139

@@ -143,9 +144,9 @@ func (m *fileMap) getOverlays() []*overlay {
143144
func (m *fileMap) getDirs() *persistent.Set[string] {
144145
if m.dirs == nil {
145146
m.dirs = new(persistent.Set[string])
146-
m.files.Range(func(u protocol.DocumentURI, _ file.Handle) {
147-
m.addDirs(u)
148-
})
147+
for uri := range m.files.All() {
148+
m.addDirs(uri)
149+
}
149150
}
150151
return m.dirs
151152
}

gopls/internal/cache/filemap_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ func TestFileMap(t *testing.T) {
8383
}
8484

8585
var gotFiles []string
86-
m.foreach(func(uri protocol.DocumentURI, _ file.Handle) {
86+
for uri := range m.all() {
8787
gotFiles = append(gotFiles, normalize(uri.Path()))
88-
})
88+
}
8989
sort.Strings(gotFiles)
9090
if diff := cmp.Diff(test.wantFiles, gotFiles); diff != "" {
9191
t.Errorf("Files mismatch (-want +got):\n%s", diff)
@@ -100,9 +100,9 @@ func TestFileMap(t *testing.T) {
100100
}
101101

102102
var gotDirs []string
103-
m.getDirs().Range(func(dir string) {
103+
for dir := range m.getDirs().All() {
104104
gotDirs = append(gotDirs, normalize(dir))
105-
})
105+
}
106106
sort.Strings(gotDirs)
107107
if diff := cmp.Diff(test.wantDirs, gotDirs); diff != "" {
108108
t.Errorf("Dirs mismatch (-want +got):\n%s", diff)

gopls/internal/cache/load.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,11 @@ func (s *Snapshot) load(ctx context.Context, allowNetwork AllowNetwork, scopes .
262262
s.mu.Lock()
263263

264264
// Assert the invariant s.packages.Get(id).m == s.meta.metadata[id].
265-
s.packages.Range(func(id PackageID, ph *packageHandle) {
265+
for id, ph := range s.packages.All() {
266266
if s.meta.Packages[id] != ph.mp {
267267
panic("inconsistent metadata")
268268
}
269-
})
269+
}
270270

271271
// Compute the minimal metadata updates (for Clone)
272272
// required to preserve the above invariant.

gopls/internal/cache/snapshot.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,11 @@ func (s *Snapshot) Templates() map[protocol.DocumentURI]file.Handle {
344344
defer s.mu.Unlock()
345345

346346
tmpls := map[protocol.DocumentURI]file.Handle{}
347-
s.files.foreach(func(k protocol.DocumentURI, fh file.Handle) {
347+
for k, fh := range s.files.all() {
348348
if s.FileKind(fh) == file.Tmpl {
349349
tmpls[k] = fh
350350
}
351-
})
351+
}
352352
return tmpls
353353
}
354354

@@ -864,13 +864,13 @@ func (s *Snapshot) addKnownSubdirs(patterns map[protocol.RelativePattern]unit, w
864864
s.mu.Lock()
865865
defer s.mu.Unlock()
866866

867-
s.files.getDirs().Range(func(dir string) {
867+
for dir := range s.files.getDirs().All() {
868868
for _, wsDir := range wsDirs {
869869
if pathutil.InDir(wsDir, dir) {
870870
patterns[protocol.RelativePattern{Pattern: filepath.ToSlash(dir)}] = unit{}
871871
}
872872
}
873-
})
873+
}
874874
}
875875

876876
// watchSubdirs reports whether gopls should request separate file watchers for
@@ -912,11 +912,11 @@ func (s *Snapshot) filesInDir(uri protocol.DocumentURI) []protocol.DocumentURI {
912912
return nil
913913
}
914914
var files []protocol.DocumentURI
915-
s.files.foreach(func(uri protocol.DocumentURI, _ file.Handle) {
915+
for uri := range s.files.all() {
916916
if pathutil.InDir(dir, uri.Path()) {
917917
files = append(files, uri)
918918
}
919-
})
919+
}
920920
return files
921921
}
922922

@@ -1029,13 +1029,11 @@ func (s *Snapshot) clearShouldLoad(scopes ...loadScope) {
10291029
case packageLoadScope:
10301030
scopePath := PackagePath(scope)
10311031
var toDelete []PackageID
1032-
s.shouldLoad.Range(func(id PackageID, pkgPaths []PackagePath) {
1033-
for _, pkgPath := range pkgPaths {
1034-
if pkgPath == scopePath {
1035-
toDelete = append(toDelete, id)
1036-
}
1032+
for id, pkgPaths := range s.shouldLoad.All() {
1033+
if slices.Contains(pkgPaths, scopePath) {
1034+
toDelete = append(toDelete, id)
10371035
}
1038-
})
1036+
}
10391037
for _, id := range toDelete {
10401038
s.shouldLoad.Delete(id)
10411039
}
@@ -1183,7 +1181,7 @@ func (s *Snapshot) reloadWorkspace(ctx context.Context) {
11831181
var scopes []loadScope
11841182
var seen map[PackagePath]bool
11851183
s.mu.Lock()
1186-
s.shouldLoad.Range(func(_ PackageID, pkgPaths []PackagePath) {
1184+
for _, pkgPaths := range s.shouldLoad.All() {
11871185
for _, pkgPath := range pkgPaths {
11881186
if seen == nil {
11891187
seen = make(map[PackagePath]bool)
@@ -1194,7 +1192,7 @@ func (s *Snapshot) reloadWorkspace(ctx context.Context) {
11941192
seen[pkgPath] = true
11951193
scopes = append(scopes, packageLoadScope(pkgPath))
11961194
}
1197-
})
1195+
}
11981196
s.mu.Unlock()
11991197

12001198
if len(scopes) == 0 {
@@ -1886,13 +1884,13 @@ func deleteMostRelevantModFile(m *persistent.Map[protocol.DocumentURI, *memoize.
18861884
var mostRelevant protocol.DocumentURI
18871885
changedFile := changed.Path()
18881886

1889-
m.Range(func(modURI protocol.DocumentURI, _ *memoize.Promise) {
1887+
for modURI := range m.All() {
18901888
if len(modURI) > len(mostRelevant) {
18911889
if pathutil.InDir(modURI.DirPath(), changedFile) {
18921890
mostRelevant = modURI
18931891
}
18941892
}
1895-
})
1893+
}
18961894
if mostRelevant != "" {
18971895
m.Delete(mostRelevant)
18981896
}

gopls/internal/cache/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ func (s *Snapshot) Vulnerabilities(modfiles ...protocol.DocumentURI) map[protoco
11711171
defer s.mu.Unlock()
11721172

11731173
if len(modfiles) == 0 { // empty means all modfiles
1174-
modfiles = s.vulns.Keys()
1174+
modfiles = slices.Collect(s.vulns.Keys())
11751175
}
11761176
for _, modfile := range modfiles {
11771177
vuln, _ := s.vulns.Get(modfile)

gopls/internal/util/persistent/map.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package persistent
99

1010
import (
1111
"fmt"
12+
"iter"
1213
"math/rand"
1314
"strings"
1415
"sync/atomic"
@@ -57,10 +58,10 @@ func (m *Map[K, V]) String() string {
5758
var buf strings.Builder
5859
buf.WriteByte('{')
5960
var sep string
60-
m.Range(func(k K, v V) {
61+
for k, v := range m.All() {
6162
fmt.Fprintf(&buf, "%s%v: %v", sep, k, v)
6263
sep = ", "
63-
})
64+
}
6465
buf.WriteByte('}')
6566
return buf.String()
6667
}
@@ -149,29 +150,29 @@ func (pm *Map[K, V]) Clear() {
149150
pm.root = nil
150151
}
151152

152-
// Keys returns all keys present in the map.
153-
func (pm *Map[K, V]) Keys() []K {
154-
var keys []K
155-
pm.root.forEach(func(k, _ any) {
156-
keys = append(keys, k.(K))
157-
})
158-
return keys
153+
// Keys returns the ascending sequence of keys present in the map.
154+
func (pm *Map[K, V]) Keys() iter.Seq[K] {
155+
return func(yield func(K) bool) {
156+
pm.root.forEach(func(k, _ any) bool {
157+
return yield(k.(K))
158+
})
159+
}
159160
}
160161

161-
// Range calls f sequentially in ascending key order for all entries in the map.
162-
func (pm *Map[K, V]) Range(f func(key K, value V)) {
163-
pm.root.forEach(func(k, v any) {
164-
f(k.(K), v.(V))
165-
})
162+
// All returns the sequence of map entries in ascending key order.
163+
func (pm *Map[K, V]) All() iter.Seq2[K, V] {
164+
return func(yield func(K, V) bool) {
165+
pm.root.forEach(func(k, v any) bool {
166+
return yield(k.(K), v.(V))
167+
})
168+
}
166169
}
167170

168-
func (node *mapNode) forEach(f func(key, value any)) {
169-
if node == nil {
170-
return
171-
}
172-
node.left.forEach(f)
173-
f(node.key, node.value.value)
174-
node.right.forEach(f)
171+
func (node *mapNode) forEach(yield func(key, value any) bool) bool {
172+
return node == nil ||
173+
node.left.forEach(yield) &&
174+
yield(node.key, node.value.value) &&
175+
node.right.forEach(yield)
175176
}
176177

177178
// Get returns the map value associated with the specified key.

gopls/internal/util/persistent/map_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,12 @@ func (vm *validatedMap) validate(t *testing.T) {
240240
}
241241

242242
actualMap := make(map[int]int, len(vm.expected))
243-
vm.impl.Range(func(key, value int) {
243+
for key, value := range vm.impl.All() {
244244
if other, ok := actualMap[key]; ok {
245245
t.Fatalf("key is present twice, key: %d, first value: %d, second value: %d", key, value, other)
246246
}
247247
actualMap[key] = value
248-
})
248+
}
249249

250250
assertSameMap(t, actualMap, vm.expected)
251251
}

gopls/internal/util/persistent/set.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
package persistent
66

7-
import "golang.org/x/tools/gopls/internal/util/constraints"
7+
import (
8+
"iter"
9+
10+
"golang.org/x/tools/gopls/internal/util/constraints"
11+
)
812

913
// Set is a collection of elements of type K.
1014
//
@@ -43,12 +47,14 @@ func (s *Set[K]) Contains(key K) bool {
4347
return ok
4448
}
4549

46-
// Range calls f sequentially in ascending key order for all entries in the set.
47-
func (s *Set[K]) Range(f func(key K)) {
48-
if s.impl != nil {
49-
s.impl.Range(func(key K, _ struct{}) {
50-
f(key)
51-
})
50+
// All returns the sequence of set elements in ascending order.
51+
func (s *Set[K]) All() iter.Seq[K] {
52+
return func(yield func(K) bool) {
53+
if s.impl != nil {
54+
s.impl.root.forEach(func(k, _ any) bool {
55+
return yield(k.(K))
56+
})
57+
}
5258
}
5359
}
5460

gopls/internal/util/persistent/set_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ func diff[K constraints.Ordered](got *persistent.Set[K], want []K) string {
111111
wantSet[w] = struct{}{}
112112
}
113113
var diff []string
114-
got.Range(func(key K) {
114+
for key := range got.All() {
115115
if _, ok := wantSet[key]; !ok {
116116
diff = append(diff, fmt.Sprintf("+%v", key))
117117
}
118-
})
118+
}
119119
for key := range wantSet {
120120
if !got.Contains(key) {
121121
diff = append(diff, fmt.Sprintf("-%v", key))

0 commit comments

Comments
 (0)