lifecycle/layers/digest.go

47 lines
749 B
Go

package layers
import (
"hash"
"sync"
)
// concurrentHasher wraps a hash.Hash so that writes to it
// happen on a separate go routine.
type concurrentHasher struct {
hash hash.Hash
wg sync.WaitGroup
buffers chan []byte
}
func newConcurrentHasher(h hash.Hash) *concurrentHasher {
ch := &concurrentHasher{
hash: h,
buffers: make(chan []byte, 10),
}
go func() {
for b := range ch.buffers {
_, _ = ch.hash.Write(b)
ch.wg.Done()
}
}()
return ch
}
func (ch *concurrentHasher) Write(p []byte) (int, error) {
cp := make([]byte, len(p))
copy(cp, p)
ch.wg.Add(1)
ch.buffers <- cp
return len(p), nil
}
func (ch *concurrentHasher) Sum(b []byte) []byte {
ch.wg.Wait()
close(ch.buffers)
return ch.hash.Sum(b)
}