github.com/igoogolx/clash@v1.19.8/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  }