chore: use io.ReadFull instead of io.ReadAll for DataAsync (#12795)

Since the final size is already known, no need to `ReadAll` a `LimitedReader`: directly `ReadFull` a properly sized buffer.

Tests are already present in `blob_test.go` (a failure can be triggered by creating a smaller `buf`).

`go test -run=TestBlob_Data -bench=Blob_Data -benchmem` before:
```
Benchmark_Blob_Data-18             43964             28727 ns/op            1373 B/op         11 allocs/op
```
After:
```
Benchmark_Blob_Data-18             41308             27679 ns/op             846 B/op         10 allocs/op
```

🎉 one allocation spared!

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12795
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
This commit is contained in:
oliverpool 2026-05-28 23:51:15 +02:00 committed by Gusted
commit bd0b44d01d
2 changed files with 4 additions and 3 deletions

View file

@ -83,13 +83,14 @@ func (b *Blob) DataAsync() (io.ReadCloser, error) {
}
if size < 4096 {
bs, err := io.ReadAll(io.LimitReader(rd, size))
buf := make([]byte, size)
_, err := io.ReadFull(rd, buf)
defer cancel()
if err != nil {
return nil, err
}
_, err = rd.Discard(1)
return io.NopCloser(bytes.NewReader(bs)), err
return io.NopCloser(bytes.NewReader(buf)), err
}
return &blobReader{

View file

@ -143,7 +143,7 @@ func Benchmark_Blob_Data(b *testing.B) {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
for b.Loop() {
r, err := testBlob.DataAsync()
if err != nil {
b.Fatal(err)