xxh64.go
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
}