github.com/scottcagno/storage@v1.8.0/pkg/hash/murmur3/murmur.go (about) 1 /* 2 * // Copyright (c) 2021. Scott Cagno. All rights reserved. 3 * // The license can be found in the root of this project; see LICENSE. 4 */ 5 6 package murmur3 7 8 /* 9 Native (and fast) implementation of Austin Appleby's MurmurHash3. 10 Reference implementation: 11 http://code.google.com/p/smhasher/wiki/MurmurHash3 12 13 For more information, see below: 14 https://sites.google.com/site/murmurhash/ 15 https://sites.google.com/site/murmurhash/statistics 16 */ 17 18 type bmixer interface { 19 bmix(p []byte) (tail []byte) 20 Size() (n int) 21 reset() 22 } 23 24 type digest struct { 25 clen int // Digested input cumulative length. 26 tail []byte // 0 to Size()-1 bytes view of `buf'. 27 buf [16]byte // Expected (but not required) to be Size() large. 28 bmixer 29 } 30 31 func (d *digest) BlockSize() int { return 1 } 32 33 func (d *digest) Write(p []byte) (n int, err error) { 34 n = len(p) 35 d.clen += n 36 37 if len(d.tail) > 0 { 38 // Stick back pending bytes. 39 nfree := d.Size() - len(d.tail) // nfree ∈ [1, d.Size()-1]. 40 if nfree < len(p) { 41 // One full block can be formed. 42 block := append(d.tail, p[:nfree]...) 43 p = p[nfree:] 44 _ = d.bmix(block) // No tail. 45 } else { 46 // Tail's buf is large enough to prevent reallocs. 47 p = append(d.tail, p...) 48 } 49 } 50 51 d.tail = d.bmix(p) 52 53 // Keep own copy of the 0 to Size()-1 pending bytes. 54 nn := copy(d.buf[:], d.tail) 55 d.tail = d.buf[:nn] 56 57 return n, nil 58 } 59 60 func (d *digest) Reset() { 61 d.clen = 0 62 d.tail = nil 63 d.bmixer.reset() 64 }