package utils import ( "fmt" "io" "os" "sync" "github.com/cespare/xxhash/v2" ) var hashBufferPool = sync.Pool{ New: func() any { buf := make([]byte, 128*1024) return &buf }, } func getHashBuffer() *[]byte { return hashBufferPool.Get().(*[]byte) } func putHashBuffer(buf *[]byte) { hashBufferPool.Put(buf) } // ComputeXXH64 computes the XXH64 hash of a file using streaming I/O. // Uses a constant ~128KB buffer regardless of file size. // Returns the hash as a 16-character lowercase hexadecimal string. func ComputeXXH64(filepath string) (string, error) { file, err := os.Open(filepath) if err != nil { return "", fmt.Errorf("failed to open file: %w", err) } defer func() { _ = file.Close() }() hashBufPtr := getHashBuffer() defer putHashBuffer(hashBufPtr) h := xxhash.New() if _, err := io.CopyBuffer(h, file, *hashBufPtr); err != nil { return "", fmt.Errorf("failed to read file: %w", err) } return fmt.Sprintf("%016x", h.Sum64()), nil }