Skip to content

Commit 269065c

Browse files
committed
[perf] cache nix.searchSystem
1 parent ca4d880 commit 269065c

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

internal/nix/nix.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type PrintDevEnvArgs struct {
4444
// PrintDevEnv calls `nix print-dev-env -f <path>` and returns its output. The output contains
4545
// all the environment variables and bash functions required to create a nix shell.
4646
func (*Nix) PrintDevEnv(ctx context.Context, args *PrintDevEnvArgs) (*PrintDevEnvOut, error) {
47+
defer debug.FunctionTimer().End()
4748
defer trace.StartRegion(ctx, "nixPrintDevEnv").End()
4849

4950
var data []byte

internal/nix/search.go

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package nix
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"fmt"
67
"os"
78
"os/exec"
9+
"path/filepath"
810
"strings"
911

1012
"github.com/pkg/errors"
1113
"go.jetpack.io/devbox/internal/debug"
14+
"go.jetpack.io/devbox/internal/xdg"
1215
)
1316

1417
var (
@@ -19,10 +22,10 @@ var (
1922
type Info struct {
2023
// attribute key is different in flakes vs legacy so we should only use it
2124
// if we know exactly which version we are using
22-
AttributeKey string
23-
PName string
24-
Summary string
25-
Version string
25+
AttributeKey string `json:"attribute"`
26+
PName string `json:"pname"`
27+
Summary string `json:"summary"`
28+
Version string `json:"version"`
2629
}
2730

2831
func (i *Info) String() string {
@@ -34,7 +37,7 @@ func Search(url string) (map[string]*Info, error) {
3437
// TODO implement runx search
3538
return map[string]*Info{}, nil
3639
}
37-
return searchSystem(url, "")
40+
return searchSystemUsingCache(url, "")
3841
}
3942

4043
func parseSearchResults(data []byte) map[string]*Info {
@@ -106,3 +109,75 @@ func searchSystem(url, system string) (map[string]*Info, error) {
106109
}
107110
return parseSearchResults(out), nil
108111
}
112+
113+
type searchSystemCache struct {
114+
QueryToInfo map[string]map[string]*Info `json:"query_to_info"`
115+
}
116+
117+
const (
118+
searchSystemCacheSubDir = "devbox/nix"
119+
searchSystemCacheFileName = "search-system-cache.json"
120+
)
121+
122+
var cache = searchSystemCache{}
123+
124+
func searchSystemUsingCache(url, system string) (map[string]*Info, error) {
125+
if system != "" {
126+
return searchSystem(url, system)
127+
}
128+
129+
if cache.QueryToInfo == nil {
130+
contents, err := readSearchSystemCacheFile()
131+
if err != nil {
132+
return nil, err
133+
}
134+
cache.QueryToInfo = contents
135+
}
136+
137+
if result := cache.QueryToInfo[url]; result != nil {
138+
return result, nil
139+
}
140+
141+
info, err := searchSystem(url, system)
142+
if err != nil {
143+
return nil, err
144+
}
145+
146+
cache.QueryToInfo[url] = info
147+
if err := writeSearchSystemCacheFile(cache.QueryToInfo); err != nil {
148+
return nil, err
149+
}
150+
151+
return info, nil
152+
}
153+
154+
func readSearchSystemCacheFile() (map[string]map[string]*Info, error) {
155+
contents, err := os.ReadFile(xdg.CacheSubpath(filepath.Join(searchSystemCacheSubDir, searchSystemCacheFileName)))
156+
if err != nil {
157+
if os.IsNotExist(err) {
158+
return make(map[string]map[string]*Info), nil
159+
}
160+
return nil, err
161+
}
162+
var result map[string]map[string]*Info
163+
if err := json.Unmarshal(contents, &result); err != nil {
164+
return nil, err
165+
}
166+
return result, nil
167+
}
168+
169+
func writeSearchSystemCacheFile(contents map[string]map[string]*Info) error {
170+
buf := bytes.Buffer{}
171+
enc := json.NewEncoder(&buf)
172+
enc.SetIndent("", " ")
173+
err := enc.Encode(contents)
174+
if err != nil {
175+
return err
176+
}
177+
dir := xdg.CacheSubpath(searchSystemCacheSubDir)
178+
if err := os.MkdirAll(dir, 0o755); err != nil {
179+
return err
180+
}
181+
path := filepath.Join(dir, searchSystemCacheFileName)
182+
return os.WriteFile(path, buf.Bytes(), 0o644)
183+
}

0 commit comments

Comments
 (0)