Skip to content

Commit 6cd19f6

Browse files
authored
perf(expression): use streaming hash in hashFiles() to reduce memory usage (#83)
1 parent dbabd99 commit 6cd19f6

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

internal/expression/evaluator.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/sha256"
55
"encoding/hex"
66
"fmt"
7+
"io"
78
"os"
89
"path/filepath"
910
"sort"
@@ -373,6 +374,7 @@ func evalEndsWith(args []Node, ctx *EvaluationContext) (bool, error) {
373374

374375
// evalHashFiles evaluates the hashFiles(pattern...) function.
375376
// Returns the SHA256 hash of the contents of files matching the patterns.
377+
// Uses streaming hash to avoid loading all file contents into memory.
376378
func evalHashFiles(args []Node, ctx *EvaluationContext) (string, error) {
377379
if len(args) == 0 {
378380
return "", nil
@@ -387,7 +389,9 @@ func evalHashFiles(args []Node, ctx *EvaluationContext) (string, error) {
387389
}
388390
}
389391

390-
var allBytes []byte
392+
h := sha256.New()
393+
hasContent := false
394+
391395
for _, arg := range args {
392396
patternVal, err := evaluateNode(arg, ctx)
393397
if err != nil {
@@ -409,20 +413,26 @@ func evalHashFiles(args []Node, ctx *EvaluationContext) (string, error) {
409413
if err != nil || info.IsDir() {
410414
continue
411415
}
412-
data, err := os.ReadFile(match)
416+
417+
f, err := os.Open(match)
418+
if err != nil {
419+
continue
420+
}
421+
422+
_, err = io.Copy(h, f)
423+
f.Close()
413424
if err != nil {
414425
continue
415426
}
416-
allBytes = append(allBytes, data...)
427+
hasContent = true
417428
}
418429
}
419430

420-
if len(allBytes) == 0 {
431+
if !hasContent {
421432
return "", nil
422433
}
423434

424-
hash := sha256.Sum256(allBytes)
425-
return hex.EncodeToString(hash[:]), nil
435+
return hex.EncodeToString(h.Sum(nil)), nil
426436
}
427437

428438
// toBool converts a value to a boolean.

0 commit comments

Comments
 (0)