|
|
@@ -94,14 +94,25 @@ func calcDatasetSize(epoch int) uint64 {
|
|
|
// reused between hash runs instead of requiring new ones to be created.
|
|
|
type hasher func(dest []byte, data []byte)
|
|
|
|
|
|
-// makeHasher creates a repetitive hasher, allowing the same hash data structures
|
|
|
-// to be reused between hash runs instead of requiring new ones to be created.
|
|
|
-// The returned function is not thread safe!
|
|
|
+// makeHasher creates a repetitive hasher, allowing the same hash data structures to
|
|
|
+// be reused between hash runs instead of requiring new ones to be created. The returned
|
|
|
+// function is not thread safe!
|
|
|
func makeHasher(h hash.Hash) hasher {
|
|
|
+ // sha3.state supports Read to get the sum, use it to avoid the overhead of Sum.
|
|
|
+ // Read alters the state but we reset the hash before every operation.
|
|
|
+ type readerHash interface {
|
|
|
+ hash.Hash
|
|
|
+ Read([]byte) (int, error)
|
|
|
+ }
|
|
|
+ rh, ok := h.(readerHash)
|
|
|
+ if !ok {
|
|
|
+ panic("can't find Read method on hash")
|
|
|
+ }
|
|
|
+ outputLen := rh.Size()
|
|
|
return func(dest []byte, data []byte) {
|
|
|
- h.Write(data)
|
|
|
- h.Sum(dest[:0])
|
|
|
- h.Reset()
|
|
|
+ rh.Reset()
|
|
|
+ rh.Write(data)
|
|
|
+ rh.Read(dest[:outputLen])
|
|
|
}
|
|
|
}
|
|
|
|