Since we only need to retrieve the file names, we can use
`(*os.File).Readdirnames` to avoid reading the whole file info for
better performance.
Sample benchmark:
func Benchmark_Readdir(b *testing.B) {
for i := 0; i < b.N; i++ {
f, err := os.Open("/")
if err != nil {
b.Fatal(err)
}
_, err = f.Readdir(-1)
if err != nil {
f.Close()
b.Fatal(err)
}
f.Close()
}
}
func Benchmark_Readdirnames(b *testing.B) {
for i := 0; i < b.N; i++ {
f, err := os.Open("/")
if err != nil {
b.Fatal(err)
}
_, err = f.Readdirnames(-1)
if err != nil {
f.Close()
b.Fatal(err)
}
f.Close()
}
}
goos: linux
goarch: amd64
pkg: github.com/osbuild/osbuild-composer/internal/jsondb
cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
Benchmark_Readdir-16 31304 33551 ns/op 5638 B/op 70 allocs/op
Benchmark_Readdirnames-16 128443 12124 ns/op 1228 B/op 30 allocs/op
PASS
ok github.com/osbuild/osbuild-composer/internal/jsondb 3.098s
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
ioutil has been deprecated since go 1.16, this fixes all of the
deprecated functions we are using:
ioutil.ReadFile -> os.ReadFile
ioutil.ReadAll -> io.ReadAll
ioutil.WriteFile -> os.WriteFile
ioutil.TempFile -> os.CreateTemp
ioutil.TempDir -> os.MkdirTemp
All of the above are a simple name change, the function arguments and
results are exactly the same as before.
ioutil.ReadDir -> os.ReadDir
now returns a os.DirEntry but the IsDir and Name functions work the
same. The difference is that the FileInfo must be retrieved with the
Info() function which can also return an error.
These were identified by running:
golangci-lint run --build-tags=integration ./...
The directory created by `T.TempDir` is automatically removed when the
test and all its subtests complete.
Reference: https://pkg.go.dev/testing#T.TempDir
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
weldr's store is quite complex and handled serialization itself. Move
that part out into a separate package `jsondb`.
This package is more generic than the store needs: it can write an
arbitrary amount of JSON documents while the store only needs one:
state.json. This is in preparation for future work, which introduces a
queue package that builds on top of `jsondb`.