github.com/kelleygo/clashcore@v1.0.2/common/murmur3/murmur.go (about) 1 package murmur3 2 3 type bmixer interface { 4 bmix(p []byte) (tail []byte) 5 Size() (n int) 6 reset() 7 } 8 9 type digest struct { 10 clen int // Digested input cumulative length. 11 tail []byte // 0 to Size()-1 bytes view of `buf'. 12 buf [16]byte // Expected (but not required) to be Size() large. 13 seed uint32 // Seed for initializing the hash. 14 bmixer 15 } 16 17 func (d *digest) BlockSize() int { return 1 } 18 19 func (d *digest) Write(p []byte) (n int, err error) { 20 n = len(p) 21 d.clen += n 22 23 if len(d.tail) > 0 { 24 // Stick back pending bytes. 25 nfree := d.Size() - len(d.tail) // nfree ∈ [1, d.Size()-1]. 26 if nfree < len(p) { 27 // One full block can be formed. 28 block := append(d.tail, p[:nfree]...) 29 p = p[nfree:] 30 _ = d.bmix(block) // No tail. 31 } else { 32 // Tail's buf is large enough to prevent reallocs. 33 p = append(d.tail, p...) 34 } 35 } 36 37 d.tail = d.bmix(p) 38 39 // Keep own copy of the 0 to Size()-1 pending bytes. 40 nn := copy(d.buf[:], d.tail) 41 d.tail = d.buf[:nn] 42 43 return n, nil 44 } 45 46 func (d *digest) Reset() { 47 d.clen = 0 48 d.tail = nil 49 d.bmixer.reset() 50 }