github.com/zhangyunhao116/wyhash@v0.4.1-0.20220217162229-7d42996fa899/digest_test.go (about)

     1  package wyhash
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  	"testing"
     7  
     8  	_ "unsafe" // for linkname
     9  )
    10  
    11  //go:linkname runtime_fastrand runtime.fastrand
    12  func runtime_fastrand() uint32
    13  
    14  //go:nosplit
    15  func fastrandn(n uint32) uint32 {
    16  	// This is similar to Uint32() % n, but faster.
    17  	// See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
    18  	return uint32(uint64(runtime_fastrand()) * uint64(n) >> 32)
    19  }
    20  
    21  func TestDigest(t *testing.T) {
    22  	d := NewDefault()
    23  	for size := 0; size <= 1024; size++ {
    24  		data := make([]byte, size)
    25  		for i := range data {
    26  			data[i] = byte(fastrandn(256))
    27  		}
    28  		// Random write small data.
    29  		var r int
    30  		if size == 0 {
    31  			r = 0
    32  		} else {
    33  			r = int(fastrandn(uint32(len(data))))
    34  		}
    35  		d.Write(data[:r])
    36  		d.Write(data[r:])
    37  		if d.Sum64() != Sum64(data) {
    38  			t.Fatal(size, d.Sum64(), Sum64(data))
    39  		}
    40  		d.Reset()
    41  	}
    42  
    43  	largedata := make([]byte, 1024*1024)
    44  	for i := range largedata {
    45  		largedata[i] = byte(fastrandn(256))
    46  	}
    47  
    48  	var a, b int
    49  	digest := NewDefault()
    50  	partsizelimit := 300
    51  	for {
    52  		if len(largedata)-a < 300 {
    53  			b = len(largedata) - a
    54  		} else {
    55  			b = int(fastrandn(uint32(partsizelimit)))
    56  		}
    57  		digest.Write(largedata[a : a+b])
    58  		if Sum64(largedata[:a+b]) != digest.Sum64() {
    59  			t.Fatal(a, b)
    60  		}
    61  		a += b
    62  		if a == len(largedata) {
    63  			break
    64  		}
    65  	}
    66  }
    67  
    68  func BenchmarkDigest(b *testing.B) {
    69  	sizes := []int{33, 64, 96, 128, 129, 240, 241,
    70  		512, 1024, 10 * 1024,
    71  	}
    72  
    73  	for _, size := range sizes {
    74  		b.Run(fmt.Sprintf("%d", size), func(b *testing.B) {
    75  			b.SetBytes(int64(size))
    76  			var acc uint64
    77  			data := make([]byte, size)
    78  			b.ReportAllocs()
    79  			b.ResetTimer()
    80  
    81  			for i := 0; i < b.N; i++ {
    82  				d := NewDefault()
    83  				d.Write(data)
    84  				acc = d.Sum64()
    85  			}
    86  			runtime.KeepAlive(acc)
    87  		})
    88  	}
    89  }