github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/internal/wyhash/digest_test.go (about) 1 // Copyright 2021 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package wyhash 16 17 import ( 18 "fmt" 19 "runtime" 20 "testing" 21 22 _ "unsafe" // for linkname 23 ) 24 25 //go:linkname runtime_fastrand runtime.fastrand 26 func runtime_fastrand() uint32 27 28 //go:nosplit 29 func fastrandn(n uint32) uint32 { 30 // This is similar to Uint32() % n, but faster. 31 // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ 32 return uint32(uint64(runtime_fastrand()) * uint64(n) >> 32) 33 } 34 35 func TestDigest(t *testing.T) { 36 d := NewDefault() 37 for size := 0; size <= 1024; size++ { 38 data := make([]byte, size) 39 for i := range data { 40 data[i] = byte(fastrandn(256)) 41 } 42 // Random write small data. 43 var r int 44 if size == 0 { 45 r = 0 46 } else { 47 r = int(fastrandn(uint32(len(data)))) 48 } 49 d.Write(data[:r]) 50 d.Write(data[r:]) 51 if d.Sum64() != Sum64(data) { 52 t.Fatal(size, d.Sum64(), Sum64(data)) 53 } 54 d.Reset() 55 } 56 57 largedata := make([]byte, 1024*1024) 58 for i := range largedata { 59 largedata[i] = byte(fastrandn(256)) 60 } 61 62 var a, b int 63 digest := NewDefault() 64 partsizelimit := 300 65 for { 66 if len(largedata)-a < 300 { 67 b = len(largedata) - a 68 } else { 69 b = int(fastrandn(uint32(partsizelimit))) 70 } 71 digest.Write(largedata[a : a+b]) 72 if Sum64(largedata[:a+b]) != digest.Sum64() { 73 t.Fatal(a, b) 74 } 75 a += b 76 if a == len(largedata) { 77 break 78 } 79 } 80 } 81 82 func BenchmarkDigest(b *testing.B) { 83 sizes := []int{33, 64, 96, 128, 129, 240, 241, 84 512, 1024, 10 * 1024, 85 } 86 87 for _, size := range sizes { 88 b.Run(fmt.Sprintf("%d", size), func(b *testing.B) { 89 b.SetBytes(int64(size)) 90 var acc uint64 91 data := make([]byte, size) 92 b.ReportAllocs() 93 b.ResetTimer() 94 95 for i := 0; i < b.N; i++ { 96 d := NewDefault() 97 d.Write(data) 98 acc = d.Sum64() 99 } 100 runtime.KeepAlive(acc) 101 }) 102 } 103 }