Skip to content

Commit e7048d5

Browse files
committed
gopls/internal/lsp/filecache: front with a 100MB in-memory LRU cache
Put a 100MB in-memory LRU cache in front of the filecache, to reduce I/O for repeated cache access, such as we observe with workspace diagnostics or implements queries. Updates golang/go#60089 For golang/go#57987 Change-Id: I01a1fcca7dcf26416d4cdb578a7a2674765c9f08 Reviewed-on: https://go-review.googlesource.com/c/tools/+/494100 Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Alan Donovan <[email protected]> TryBot-Result: Gopher Robot <[email protected]> gopls-CI: kokoro <[email protected]>
1 parent 8c0fcd2 commit e7048d5

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

gopls/internal/lsp/filecache/filecache.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"time"
4141

4242
"golang.org/x/tools/gopls/internal/bug"
43+
"golang.org/x/tools/gopls/internal/lsp/lru"
4344
"golang.org/x/tools/internal/lockedfile"
4445
)
4546

@@ -51,11 +52,28 @@ func Start() {
5152
go getCacheDir()
5253
}
5354

55+
// As an optimization, use a 100MB in-memory LRU cache in front of filecache
56+
// operations. This reduces I/O for operations such as diagnostics or
57+
// implementations that repeatedly access the same cache entries.
58+
var memCache = lru.New(100 * 1e6)
59+
60+
type memKey struct {
61+
kind string
62+
key [32]byte
63+
}
64+
5465
// Get retrieves from the cache and returns a newly allocated
5566
// copy of the value most recently supplied to Set(kind, key),
5667
// possibly by another process.
5768
// Get returns ErrNotFound if the value was not found.
5869
func Get(kind string, key [32]byte) ([]byte, error) {
70+
// First consult the read-through memory cache.
71+
// Note that memory cache hits do not update the times
72+
// used for LRU eviction of the file-based cache.
73+
if value := memCache.Get(memKey{kind, key}); value != nil {
74+
return value.([]byte), nil
75+
}
76+
5977
iolimit <- struct{}{} // acquire a token
6078
defer func() { <-iolimit }() // release a token
6179

@@ -112,6 +130,7 @@ func Get(kind string, key [32]byte) ([]byte, error) {
112130
return nil, fmt.Errorf("failed to update access time: %w", err)
113131
}
114132

133+
memCache.Set(memKey{kind, key}, value, len(value))
115134
return value, nil
116135
}
117136

@@ -121,6 +140,8 @@ var ErrNotFound = fmt.Errorf("not found")
121140

122141
// Set updates the value in the cache.
123142
func Set(kind string, key [32]byte, value []byte) error {
143+
memCache.Set(memKey{kind, key}, value, len(value))
144+
124145
iolimit <- struct{}{} // acquire a token
125146
defer func() { <-iolimit }() // release a token
126147

0 commit comments

Comments
 (0)